SegmentImporter.java
12.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/*
* Decompiled with CFR 0_118.
*
* Could not load the following classes:
* com.day.cq.polling.importer.ImportException
* com.day.cq.polling.importer.Importer
* com.day.cq.wcm.webservicesupport.Configuration
* com.day.cq.wcm.webservicesupport.ConfigurationManager
* com.day.cq.wcm.webservicesupport.ConfigurationManagerFactory
* org.apache.commons.lang.StringUtils
* org.apache.felix.scr.annotations.Component
* org.apache.felix.scr.annotations.Property
* org.apache.felix.scr.annotations.Reference
* org.apache.felix.scr.annotations.Service
* org.apache.sling.api.resource.ModifiableValueMap
* org.apache.sling.api.resource.PersistenceException
* org.apache.sling.api.resource.Resource
* org.apache.sling.api.resource.ResourceResolver
* org.apache.sling.api.resource.ResourceUtil
* org.apache.sling.api.resource.ValueMap
* org.apache.sling.commons.osgi.PropertiesUtil
* org.osgi.service.component.ComponentContext
* org.slf4j.Logger
* org.slf4j.LoggerFactory
*/
package com.day.cq.analytics.testandtarget.impl;
import com.day.cq.analytics.testandtarget.ListSegmentsRequest;
import com.day.cq.analytics.testandtarget.Segment;
import com.day.cq.analytics.testandtarget.TestandtargetException;
import com.day.cq.analytics.testandtarget.TestandtargetService;
import com.day.cq.analytics.testandtarget.impl.ListSegmentsRequestImpl;
import com.day.cq.polling.importer.ImportException;
import com.day.cq.polling.importer.Importer;
import com.day.cq.wcm.webservicesupport.Configuration;
import com.day.cq.wcm.webservicesupport.ConfigurationManager;
import com.day.cq.wcm.webservicesupport.ConfigurationManagerFactory;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component(metatype=1, label="Day CQ Analytics Segment Importer", description="Imports segments defined in Test and Target into the CQ instance.")
@Service
@Property(name="importer.scheme", value={"adobe-target-segments"}, propertyPrivate=1)
public class SegmentImporter
implements Importer {
private static final boolean DEFAULT_ENABLED = true;
private static final String PN_SEGMENT_ORIGIN = "source";
private static final String PN_SEGMENT_HIDDEN = "hidden";
private static final String PN_SEGMENT_TYPE = "type";
private static final String PN_SEGMENT_SOURCE_PRODUCT = "sourceProductName";
private static final String PN_SEGMENT_EDIT_URL = "editURL";
private static final String PN_SEGMENT_AUDIENCE_JSON = "audienceJson";
private static final String PN_CLOUD_CONFIG_PATH = "cloudConfigurationPath";
private static final String PN_LAST_SUCCESSFUL_IMPORT_TIMESTAMP = "lastSuccessfulImportTimestamp";
private static final String TYPE_REUSABLE = "reusable";
@Property(label="Enabled", description="Controls whether this importer is enabled or not. Defaults to true on author instances and false on publish instances.", boolValue={1})
private static final String PROPERTY_ENABLED = "cq.analytics.testandtarget.segmentimporter.enabled";
private static final Logger log = LoggerFactory.getLogger(SegmentImporter.class);
@Reference
private TestandtargetService testandtargetService;
@Reference
private ConfigurationManagerFactory configurationManagerFactory;
private boolean enabled;
protected void activate(ComponentContext ctx) {
this.enabled = PropertiesUtil.toBoolean(ctx.getProperties().get("cq.analytics.testandtarget.segmentimporter.enabled"), (boolean)true);
}
public void importData(String scheme, String dataSource, Resource target) throws ImportException {
if (!this.enabled) {
log.debug("Component is not enabled, skipping import.");
return;
}
ResourceResolver resourceResolver = target.getResourceResolver();
log.info("Importing in {} with dataSource {}", (Object)target.getPath(), (Object)dataSource);
Resource cloudConfig = resourceResolver.getResource(dataSource);
if (cloudConfig == null) {
log.warn("Unable to import segments at {} since there is no resource at path {}", (Object)target.getPath(), (Object)dataSource);
return;
}
ConfigurationManager configurationManager = this.configurationManagerFactory.getConfigurationManager(resourceResolver);
Configuration config = configurationManager.getConfiguration(cloudConfig.getPath());
if (config == null) {
log.warn("Unable to import segments at {} since the resource at {} can not be adapted to a '{}'", new Object[]{target.getPath(), cloudConfig.getPath(), Configuration.class.getName()});
return;
}
try {
ValueMap targetProps = (ValueMap)target.adaptTo(ModifiableValueMap.class);
long lastImported = targetProps != null ? (Long)targetProps.get("lastSuccessfulImportTimestamp", (Object)0) : 0;
Date importFrom = null;
Date importTo = null;
ListSegmentsRequestImpl listSegmentsRequest = new ListSegmentsRequestImpl();
if (lastImported > 0) {
Calendar importCalender = Calendar.getInstance();
importCalender.setTimeInMillis(lastImported);
importCalender.add(6, -1);
importFrom = importCalender.getTime();
importCalender.add(6, 2);
importTo = importCalender.getTime();
listSegmentsRequest = listSegmentsRequest.modifiedFrom(importFrom).modifiedTo(importTo);
}
List<Segment> segments = this.testandtargetService.listSegments(config, listSegmentsRequest);
List<Segment> deletedSegments = null;
ArrayList<String> segmentIds = new ArrayList<String>();
for (Segment segment : segments) {
String segmentId = String.valueOf(segment.getId());
segmentIds.add(segmentId);
SegmentImporter.writeSegment(target, segment, cloudConfig.getPath(), null);
}
if (lastImported > 0) {
listSegmentsRequest = new ListSegmentsRequestImpl().deletedFrom(importFrom).deletedTo(importTo).withStatus("deleted");
deletedSegments = this.testandtargetService.listSegments(config, listSegmentsRequest);
}
Resource localTargetResource = resourceResolver.getResource(target.getPath());
ModifiableValueMap modifiableTargetProps = (ModifiableValueMap)localTargetResource.adaptTo(ModifiableValueMap.class);
modifiableTargetProps.put((Object)"lastSuccessfulImportTimestamp", (Object)Calendar.getInstance().getTimeInMillis());
resourceResolver.commit();
log.info("Wrote {} segments under {}", (Object)segments.size(), (Object)target.getPath());
this.removeDeletedSegments(target, deletedSegments);
}
catch (TestandtargetException e) {
throw new ImportException("Failed importing segments for config at " + config.getPath(), (Throwable)e);
}
catch (PersistenceException e) {
throw new ImportException("Failed importing segments for config at " + config.getPath(), (Throwable)e);
}
}
public static void writeSegment(Resource target, Segment segment, String targetConfigPath, String audienceJson) throws PersistenceException {
Map<String, String> segmentMACMetadata;
ResourceResolver resolver = target.getResourceResolver();
String segmentId = String.valueOf(segment.getId());
Resource segmentRes = ResourceUtil.getOrCreateResource((ResourceResolver)resolver, (String)(target.getPath() + "/" + segmentId), SegmentImporter.mapOfPrimaryType("cq:Page"), (String)null, (boolean)false);
HashMap<String, String> props = new HashMap<String, String>();
props.put("cq:template", "/libs/cq/personalization/templates/segment");
props.put("sling:resourceType", "cq/personalization/components/segmentpage");
Resource segmentContent = ResourceUtil.getOrCreateResource((ResourceResolver)resolver, (String)(segmentRes.getPath() + "/" + "jcr:content"), props, (String)null, (boolean)false);
ModifiableValueMap segmentMap = (ModifiableValueMap)segmentContent.adaptTo(ModifiableValueMap.class);
segmentMap.put((Object)"jcr:title", (Object)segment.getName());
segmentMap.put((Object)"source", (Object)(segment.getSource() != null ? segment.getSource() : ""));
String segmentType = segment.getType();
boolean isHidden = StringUtils.isNotEmpty((String)segmentType) ? !"reusable".equals(segmentType) : segment.getHidden();
segmentMap.put((Object)"hidden", (Object)isHidden);
if (StringUtils.isNotEmpty((String)audienceJson)) {
segmentMap.put((Object)"audienceJson", (Object)audienceJson);
}
if (StringUtils.isNotEmpty((String)targetConfigPath)) {
segmentMap.put((Object)"cloudConfigurationPath", (Object)targetConfigPath);
}
if (segment.getDescription() != null) {
segmentMap.put((Object)"jcr:description", (Object)segment.getDescription());
}
if (StringUtils.isNotEmpty((String)segmentType)) {
segmentMap.put((Object)"type", (Object)segment.getType());
}
if ((segmentMACMetadata = segment.getMarketingCloudMetadata()) != null) {
segmentMap.put((Object)"sourceProductName", (Object)segmentMACMetadata.get("sourceProductName"));
segmentMap.put((Object)"editURL", (Object)segmentMACMetadata.get("editURL"));
}
Resource traits = ResourceUtil.getOrCreateResource((ResourceResolver)resolver, (String)(segmentContent.getPath() + "/" + "traits"), (String)"cq/personalization/components/traits/logic/and", (String)null, (boolean)false);
Resource and = ResourceUtil.getOrCreateResource((ResourceResolver)resolver, (String)(traits.getPath() + "/" + "andpar"), (String)"foundation/components/parsys", (String)null, (boolean)false);
HashMap<String, String> tandtMap = new HashMap<String, String>();
tandtMap.put("sling:resourceType", "cq/personalization/components/traits/tandt");
tandtMap.put("externalId", segmentId);
Resource traitResource = ResourceUtil.getOrCreateResource((ResourceResolver)resolver, (String)(and.getPath() + "/" + "tandt"), tandtMap, (String)null, (boolean)false);
ModifiableValueMap traitMap = (ModifiableValueMap)traitResource.adaptTo(ModifiableValueMap.class);
traitMap.put((Object)"jcr:title", (Object)segment.getName());
}
private void removeDeletedSegments(Resource target, List<Segment> deletedSegments) throws PersistenceException {
int deletionCount = 0;
if (deletedSegments == null) {
return;
}
for (Segment deletedSegment : deletedSegments) {
Resource segmentResource = target.getChild(String.valueOf(deletedSegment.getId()));
if (segmentResource == null) continue;
segmentResource.getResourceResolver().delete(segmentResource);
++deletionCount;
}
if (deletionCount != 0) {
log.info("Deleted {} segments under {}", (Object)deletionCount, (Object)target.getPath());
target.getResourceResolver().commit();
}
}
private static Map<String, Object> mapOfPrimaryType(String primaryType) {
return Collections.singletonMap("jcr:primaryType", primaryType);
}
protected void bindTestandtargetService(TestandtargetService testandtargetService) {
this.testandtargetService = testandtargetService;
}
protected void unbindTestandtargetService(TestandtargetService testandtargetService) {
if (this.testandtargetService == testandtargetService) {
this.testandtargetService = null;
}
}
protected void bindConfigurationManagerFactory(ConfigurationManagerFactory configurationManagerFactory) {
this.configurationManagerFactory = configurationManagerFactory;
}
protected void unbindConfigurationManagerFactory(ConfigurationManagerFactory configurationManagerFactory) {
if (this.configurationManagerFactory == configurationManagerFactory) {
this.configurationManagerFactory = null;
}
}
}