/*
* 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
*
* 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.streams.gplus.provider;
import org.apache.streams.core.StreamsDatum;
import org.apache.streams.google.gplus.configuration.UserInfo;
import org.apache.streams.jackson.StreamsJacksonMapper;
import org.apache.streams.util.api.requests.backoff.BackOffStrategy;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.services.plus.Plus;
import com.google.api.services.plus.model.Person;
import org.apache.streams.gplus.serializer.util.GPlusPersonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.BlockingQueue;
/**
* Collects user profile information for a specific GPlus user.
*/
public class GPlusUserDataCollector extends GPlusDataCollector {
private static final Logger LOGGER = LoggerFactory.getLogger(GPlusUserDataCollector.class);
private static final ObjectMapper MAPPER = StreamsJacksonMapper.getInstance();
private static final int MAX_ATTEMPTS = 5;
static { //set up Mapper for Person objects
SimpleModule simpleModule = new SimpleModule();
simpleModule.addDeserializer(Person.class, new GPlusPersonDeserializer());
MAPPER.registerModule(simpleModule);
MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
private BackOffStrategy backOffStrategy;
private Plus plus;
private BlockingQueue<StreamsDatum> datumQueue;
private UserInfo userInfo;
/**
* GPlusUserDataCollector constructor.
* @param plus Plus
* @param backOffStrategy BackOffStrategy
* @param datumQueue BlockingQueue of StreamsDatum
* @param userInfo UserInfo
*/
public GPlusUserDataCollector(Plus plus, BackOffStrategy backOffStrategy, BlockingQueue<StreamsDatum> datumQueue, UserInfo userInfo) {
this.plus = plus;
this.backOffStrategy = backOffStrategy;
this.datumQueue = datumQueue;
this.userInfo = userInfo;
}
protected void queueUserHistory() {
try {
boolean tryAgain;
int attempts = 0;
com.google.api.services.plus.model.Person person = null;
do {
try {
person = this.plus.people().get(userInfo.getUserId()).execute();
this.backOffStrategy.reset();
tryAgain = person == null;
} catch (GoogleJsonResponseException gjre) {
tryAgain = backoffAndIdentifyIfRetry(gjre, this.backOffStrategy);
}
++attempts;
}
while (tryAgain && attempts < MAX_ATTEMPTS);
String json = MAPPER.writeValueAsString(person);
this.datumQueue.put(new StreamsDatum(json, person.getId()));
} catch (Throwable throwable) {
LOGGER.warn("Unable to pull user data for user={} : {}", userInfo.getUserId(), throwable);
if (throwable instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
}
}
@Override
public void run() {
queueUserHistory();
}
}