You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streams.apache.org by sb...@apache.org on 2014/11/08 21:13:07 UTC

[16/38] incubator-streams git commit: STREAMS-202 | Additional modifications

STREAMS-202 | Additional modifications


Project: http://git-wip-us.apache.org/repos/asf/incubator-streams/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-streams/commit/42d0ab33
Tree: http://git-wip-us.apache.org/repos/asf/incubator-streams/tree/42d0ab33
Diff: http://git-wip-us.apache.org/repos/asf/incubator-streams/diff/42d0ab33

Branch: refs/heads/STREAMS-49
Commit: 42d0ab33f20cada4bbf71eb590a4858a1f1cad2e
Parents: eba9aef
Author: Robert Douglas <rd...@w2ogroup.com>
Authored: Tue Oct 28 12:03:57 2014 -0500
Committer: Robert Douglas <rd...@w2ogroup.com>
Committed: Tue Oct 28 12:03:57 2014 -0500

----------------------------------------------------------------------
 .../google-gplus/pom.xml                        |   2 +-
 .../processor/GooglePlusTypeConverter.java      |  92 ++++++++++++++-
 .../util/GPlusPersonDeserializer.java           | 106 ++++++++++++++++-
 .../serializer/util/GooglePlusActivityUtil.java | 116 ++++++++++++++++++-
 .../google/gplus/GooglePlusPersonSerDeTest.java |  68 +++--------
 .../processor/GooglePlusTypeConverterTest.java  |  99 +++++++++++++++-
 .../test/resources/google_plus_person_jsons.txt |   2 +
 7 files changed, 414 insertions(+), 71 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/42d0ab33/streams-contrib/streams-provider-google/google-gplus/pom.xml
----------------------------------------------------------------------
diff --git a/streams-contrib/streams-provider-google/google-gplus/pom.xml b/streams-contrib/streams-provider-google/google-gplus/pom.xml
index 2a236d9..0437408 100644
--- a/streams-contrib/streams-provider-google/google-gplus/pom.xml
+++ b/streams-contrib/streams-provider-google/google-gplus/pom.xml
@@ -67,7 +67,7 @@
         <dependency>
             <groupId>com.google.apis</groupId>
             <artifactId>google-api-services-plus</artifactId>
-            <version>v1-rev118-1.17.0-rc</version>
+            <version>v1-rev184-1.19.0</version>
         </dependency>
         <dependency>
             <groupId>com.google.api-client</groupId>

http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/42d0ab33/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/processor/GooglePlusTypeConverter.java
----------------------------------------------------------------------
diff --git a/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/processor/GooglePlusTypeConverter.java b/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/processor/GooglePlusTypeConverter.java
index f23ca17..928eec9 100644
--- a/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/processor/GooglePlusTypeConverter.java
+++ b/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/processor/GooglePlusTypeConverter.java
@@ -1,7 +1,91 @@
+/*
+ * 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 com.google.gplus.processor;
 
-/**
- * Created by rdouglas on 10/27/14.
- */
-public class GooglePlusTypeConverter {
+import com.google.api.services.plus.model.Person;
+import com.google.common.collect.Lists;
+import com.google.gplus.serializer.util.GooglePlusActivityUtil;
+import org.apache.streams.core.StreamsDatum;
+import org.apache.streams.core.StreamsProcessor;
+import org.apache.streams.pojo.json.Activity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Queue;
+
+public class GooglePlusTypeConverter implements StreamsProcessor {
+    public final static String STREAMS_ID = "GooglePlusTypeConverter";
+
+    private final static Logger LOGGER = LoggerFactory.getLogger(GooglePlusTypeConverter.class);
+    private Queue<Person> inQueue;
+    private Queue<StreamsDatum> outQueue;
+    private GooglePlusActivityUtil googlePlusActivityUtil;
+    private int count = 0;
+
+    public GooglePlusTypeConverter() {}
+
+    public Queue<StreamsDatum> getProcessorOutputQueue() {
+        return outQueue;
+    }
+
+    public void setProcessorInputQueue(Queue<Person> inputQueue) {
+        inQueue = inputQueue;
+    }
+
+    @Override
+    public List<StreamsDatum> process(StreamsDatum entry) {
+        StreamsDatum result = null;
+
+        try {
+            Object item = entry.getDocument();
+
+            LOGGER.debug("{} processing {}", STREAMS_ID, item.getClass());
+            Activity activity = null;
+            if(item instanceof Person) {
+                activity = new Activity();
+
+                googlePlusActivityUtil.updateActivity((Person)item, activity);
+            }
+
+            if(activity != null) {
+                result = new StreamsDatum(activity);
+                count++;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            LOGGER.error("Exception while converting Person to Activity: {}", e.getMessage());
+        }
+
+        if( result != null )
+            return Lists.newArrayList(result);
+        else
+            return Lists.newArrayList();
+    }
+
+    @Override
+    public void prepare(Object configurationObject) {
+        googlePlusActivityUtil = new GooglePlusActivityUtil();
+    }
+
+    @Override
+    public void cleanUp() {
+        //No-op
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/42d0ab33/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/serializer/util/GPlusPersonDeserializer.java
----------------------------------------------------------------------
diff --git a/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/serializer/util/GPlusPersonDeserializer.java b/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/serializer/util/GPlusPersonDeserializer.java
index 48fed99..7ee3990 100644
--- a/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/serializer/util/GPlusPersonDeserializer.java
+++ b/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/serializer/util/GPlusPersonDeserializer.java
@@ -1,7 +1,107 @@
+/*
+ * 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 com.google.gplus.serializer.util;
 
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.IntNode;
+import com.google.api.client.util.Lists;
+import com.google.api.services.plus.model.Person;
+import org.apache.streams.jackson.StreamsJacksonMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.List;
+
 /**
- * Created by rdouglas on 10/28/14.
+ * Custom deserializer for GooglePlus' Person model
  */
-public class GPlusPersonDeserializer {
-}
+public class GPlusPersonDeserializer extends JsonDeserializer<Person> {
+    private final static Logger LOGGER = LoggerFactory.getLogger(GPlusPersonDeserializer.class);
+
+    /**
+     * Because the GooglePlus Person object contains complex objects within its hierarchy, we have to use
+     * a custom deserializer
+     *
+     * @param jsonParser
+     * @param deserializationContext
+     * @return The deserialized {@link com.google.api.services.plus.model.Person} object
+     * @throws IOException
+     * @throws JsonProcessingException
+     */
+    @Override
+    public Person deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+        ObjectMapper m = new StreamsJacksonMapper();
+
+        JsonNode node = jsonParser.getCodec().readTree(jsonParser);
+        Person person = new Person();
+        try {
+
+            person.setCircledByCount((Integer) ((IntNode) node.get("circledByCount")).numberValue());
+            person.setDisplayName(node.get("displayName").asText());
+            person.setEtag(node.get("etag").asText());
+            person.setGender(node.get("gender").asText());
+            person.setId(node.get("id").asText());
+
+            Person.Image image = new Person.Image();
+            JsonNode imageNode = node.get("image");
+            image.setIsDefault(imageNode.get("isDefault").asBoolean());
+            image.setUrl(imageNode.get("url").asText());
+            person.setImage(image);
+
+            person.setIsPlusUser(node.get("isPlusUser").asBoolean());
+            person.setKind(node.get("kind").asText());
+
+            JsonNode nameNode = node.get("name");
+            Person.Name name = m.readValue(m.writeValueAsString(nameNode), Person.Name.class);
+            person.setName(name);
+
+            person.setObjectType(node.get("objectType").asText());
+
+            List<Person.Organizations> organizations = Lists.newArrayList();
+            for (JsonNode orgNode : node.get("organizations")) {
+                Person.Organizations org = m.readValue(m.writeValueAsString(orgNode), Person.Organizations.class);
+                organizations.add(org);
+            }
+            person.setOrganizations(organizations);
+
+            person.setUrl(node.get("url").asText());
+            person.setVerified(node.get("verified").asBoolean());
+
+            List<Person.Emails> emails = Lists.newArrayList();
+            for (JsonNode emailNode : node.get("emails")) {
+                Person.Emails email = m.readValue(m.writeValueAsString(emailNode), Person.Emails.class);
+                emails.add(email);
+            }
+
+            person.setTagline(node.get("tagline").asText());
+            person.setAboutMe(node.get("aboutMe").asText());
+        } catch (Exception e) {
+            LOGGER.error("Exception while trying to deserialize a Person object: {}", e);
+        }
+
+        return person;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/42d0ab33/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/serializer/util/GooglePlusActivityUtil.java
----------------------------------------------------------------------
diff --git a/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/serializer/util/GooglePlusActivityUtil.java b/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/serializer/util/GooglePlusActivityUtil.java
index a3150c8..3fce398 100644
--- a/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/serializer/util/GooglePlusActivityUtil.java
+++ b/streams-contrib/streams-provider-google/google-gplus/src/main/java/com/google/gplus/serializer/util/GooglePlusActivityUtil.java
@@ -1,7 +1,115 @@
+/*
+ * 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 com.google.gplus.serializer.util;
 
-/**
- * Created by rdouglas on 10/27/14.
- */
+import com.google.api.services.plus.model.Person;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import org.apache.streams.exceptions.ActivitySerializerException;
+import org.apache.streams.pojo.json.Activity;
+import org.apache.streams.pojo.json.Actor;
+import org.apache.streams.pojo.json.Image;
+import org.apache.streams.pojo.json.Provider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
 public class GooglePlusActivityUtil {
-}
+    private static final Logger LOGGER = LoggerFactory.getLogger(GooglePlusActivityUtil.class);
+
+    /**
+     * Given a Person object and an activity, fill out the appropriate actor details
+     *
+     * @param item
+     * @param activity
+     * @throws ActivitySerializerException
+     */
+    public static void updateActivity(Person item, Activity activity) throws ActivitySerializerException {
+        activity.setActor(buildActor(item));
+        activity.setVerb("update");
+
+        activity.setId(formatId(activity.getVerb(),
+                Optional.fromNullable(
+                        item.getId())
+                        .orNull()));
+
+        activity.setProvider(getProvider());
+    }
+
+    /**
+     * Extract the relevant details from the passed in Person object and build
+     * an actor with them
+     *
+     * @param person
+     * @return Actor constructed with relevant Person details
+     */
+    private static Actor buildActor(Person person) {
+        Actor actor = new Actor();
+
+        actor.setUrl(person.getUrl());
+        actor.setDisplayName(person.getDisplayName());
+        actor.setId(formatId(String.valueOf(person.getId())));
+
+        if(person.getAboutMe() != null) {
+            actor.setSummary(person.getAboutMe());
+        } else if(person.getTagline() != null) {
+            actor.setSummary(person.getTagline());
+        }
+
+        Image image = new Image();
+        Person.Image googlePlusImage = person.getImage();
+
+        if(googlePlusImage != null) {
+            image.setUrl(googlePlusImage.getUrl());
+        }
+        actor.setImage(image);
+
+        Map<String, Object> extensions = new HashMap<String, Object>();
+
+        extensions.put("followers", person.getCircledByCount());
+        extensions.put("googleplus", person);
+        actor.setAdditionalProperty("extensions", extensions);
+
+        return actor;
+    }
+
+    /**
+     * Gets the common googleplus {@link org.apache.streams.pojo.json.Provider} object
+     * @return a provider object representing GooglePlus
+     */
+    public static Provider getProvider() {
+        Provider provider = new Provider();
+        provider.setId("id:providers:googleplus");
+        provider.setDisplayName("GooglePlus");
+        return provider;
+    }
+
+    /**
+     * Formats the ID to conform with the Apache Streams activity ID convention
+     * @param idparts the parts of the ID to join
+     * @return a valid Activity ID in format "id:googleplus:part1:part2:...partN"
+     */
+    public static String formatId(String... idparts) {
+        return Joiner.on(":").join(Lists.asList("id:googleplus", idparts));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/42d0ab33/streams-contrib/streams-provider-google/google-gplus/src/test/java/com/google/gplus/GooglePlusPersonSerDeTest.java
----------------------------------------------------------------------
diff --git a/streams-contrib/streams-provider-google/google-gplus/src/test/java/com/google/gplus/GooglePlusPersonSerDeTest.java b/streams-contrib/streams-provider-google/google-gplus/src/test/java/com/google/gplus/GooglePlusPersonSerDeTest.java
index 22cc340..6f6b2e3 100644
--- a/streams-contrib/streams-provider-google/google-gplus/src/test/java/com/google/gplus/GooglePlusPersonSerDeTest.java
+++ b/streams-contrib/streams-provider-google/google-gplus/src/test/java/com/google/gplus/GooglePlusPersonSerDeTest.java
@@ -19,54 +19,55 @@
 
 package com.google.gplus;
 
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.*;
 import com.fasterxml.jackson.databind.module.SimpleModule;
-import com.fasterxml.jackson.databind.node.IntNode;
-import com.google.api.client.util.Lists;
 import com.google.api.services.plus.model.Person;
+import com.google.gplus.serializer.util.GPlusPersonDeserializer;
 import com.google.gplus.serializer.util.GooglePlusActivityUtil;
 import org.apache.commons.lang.StringUtils;
 import org.apache.streams.jackson.StreamsJacksonMapper;
 import org.apache.streams.pojo.json.Activity;
 import org.apache.streams.pojo.json.Actor;
 import org.apache.streams.pojo.json.Provider;
+import org.junit.Before;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.BufferedReader;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.util.List;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
 public class GooglePlusPersonSerDeTest {
     private final static Logger LOGGER = LoggerFactory.getLogger(GooglePlusPersonSerDeTest.class);
+    private ObjectMapper objectMapper;
+    private GooglePlusActivityUtil googlePlusActivityUtil;
 
-    @Test
-    public void TestPersonObjects() {
-        ObjectMapper objectMapper = new StreamsJacksonMapper();
+    @Before
+    public void setup() {
+        objectMapper = new StreamsJacksonMapper();
         SimpleModule simpleModule = new SimpleModule();
         simpleModule.addDeserializer(Person.class, new GPlusPersonDeserializer());
         objectMapper.registerModule(simpleModule);
+        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
 
+        googlePlusActivityUtil = new GooglePlusActivityUtil();
+    }
+
+    @Test
+    public void TestPersonObjects() {
         InputStream is = GooglePlusPersonSerDeTest.class.getResourceAsStream("/google_plus_person_jsons.txt");
         InputStreamReader isr = new InputStreamReader(is);
         BufferedReader br = new BufferedReader(isr);
 
-        GooglePlusActivityUtil googlePlusActivityUtil = new GooglePlusActivityUtil();
-
         try {
             while (br.ready()) {
                 String line = br.readLine();
                 if (!StringUtils.isEmpty(line)) {
                     LOGGER.info("raw: {}", line);
-                    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                     Activity activity = new Activity();
 
                     Person person = objectMapper.readValue(line, Person.class);
@@ -93,47 +94,4 @@ public class GooglePlusPersonSerDeTest {
             LOGGER.error("Exception while testing serializability: {}", e);
         }
     }
-}
-
-class GPlusPersonDeserializer extends JsonDeserializer<Person> {
-    @Override
-    public Person deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-        ObjectMapper m = new StreamsJacksonMapper();
-
-        JsonNode node = jsonParser.getCodec().readTree(jsonParser);
-        Person person = new Person();
-
-        person.setCircledByCount((Integer)((IntNode)node.get("circledByCount")).numberValue());
-        person.setDisplayName(node.get("displayName").asText());
-        person.setEtag(node.get("etag").asText());
-        person.setGender(node.get("gender").asText());
-        person.setId(node.get("id").asText());
-
-        Person.Image image = new Person.Image();
-        JsonNode imageNode = node.get("image");
-        image.setIsDefault(imageNode.get("isDefault").asBoolean());
-        image.setUrl(imageNode.get("url").asText());
-        person.setImage(image);
-
-        person.setIsPlusUser(node.get("isPlusUser").asBoolean());
-        person.setKind(node.get("kind").asText());
-
-        JsonNode nameNode = node.get("name");
-        Person.Name name = m.readValue(m.writeValueAsString(nameNode), Person.Name.class);
-        person.setName(name);
-
-        person.setObjectType(node.get("objectType").asText());
-
-        List<Person.Organizations> organizations = Lists.newArrayList();
-        for(JsonNode orgNode : node.get("organizations")) {
-            Person.Organizations org = m.readValue(m.writeValueAsString(orgNode), Person.Organizations.class);
-            organizations.add(org);
-        }
-        person.setOrganizations(organizations);
-
-        person.setUrl(node.get("url").asText());
-        person.setVerified(node.get("verified").asBoolean());
-
-        return person;
-    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/42d0ab33/streams-contrib/streams-provider-google/google-gplus/src/test/java/com/google/gplus/processor/GooglePlusTypeConverterTest.java
----------------------------------------------------------------------
diff --git a/streams-contrib/streams-provider-google/google-gplus/src/test/java/com/google/gplus/processor/GooglePlusTypeConverterTest.java b/streams-contrib/streams-provider-google/google-gplus/src/test/java/com/google/gplus/processor/GooglePlusTypeConverterTest.java
index e4923ae..6fbdf19 100644
--- a/streams-contrib/streams-provider-google/google-gplus/src/test/java/com/google/gplus/processor/GooglePlusTypeConverterTest.java
+++ b/streams-contrib/streams-provider-google/google-gplus/src/test/java/com/google/gplus/processor/GooglePlusTypeConverterTest.java
@@ -1,7 +1,98 @@
+/*
+ * 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 com.google.gplus.processor;
 
-/**
- * Created by rdouglas on 10/28/14.
- */
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.google.api.services.plus.model.Person;
+import com.google.gplus.serializer.util.GPlusPersonDeserializer;
+import com.google.gplus.serializer.util.GooglePlusActivityUtil;
+import org.apache.commons.lang.StringUtils;
+import org.apache.streams.core.StreamsDatum;
+import org.apache.streams.jackson.StreamsJacksonMapper;
+import org.apache.streams.pojo.json.Activity;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
 public class GooglePlusTypeConverterTest {
-}
+    private final static Logger LOGGER = LoggerFactory.getLogger(GooglePlusTypeConverterTest.class);
+    private GooglePlusTypeConverter googlePlusTypeConverter;
+    private ObjectMapper objectMapper;
+
+    @Before
+    public void setup() {
+        objectMapper = new StreamsJacksonMapper();
+        SimpleModule simpleModule = new SimpleModule();
+        simpleModule.addDeserializer(Person.class, new GPlusPersonDeserializer());
+        objectMapper.registerModule(simpleModule);
+        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+
+        googlePlusTypeConverter = new GooglePlusTypeConverter();
+        googlePlusTypeConverter.prepare(null);
+    }
+
+    @Test
+    public void testProcess() {
+        InputStream is = GooglePlusTypeConverterTest.class.getResourceAsStream("/google_plus_person_jsons.txt");
+        InputStreamReader isr = new InputStreamReader(is);
+        BufferedReader br = new BufferedReader(isr);
+
+        try {
+            while (br.ready()) {
+                String line = br.readLine();
+                if (!StringUtils.isEmpty(line)) {
+                    LOGGER.info("raw: {}", line);
+                    Activity activity = new Activity();
+
+                    Person person = objectMapper.readValue(line, Person.class);
+                    StreamsDatum streamsDatum = new StreamsDatum(person);
+
+                    assertNotNull(streamsDatum.getDocument());
+
+                    List<StreamsDatum> retList = googlePlusTypeConverter.process(streamsDatum);
+                    GooglePlusActivityUtil.updateActivity(person, activity);
+
+                    assertEquals(retList.size(), 1);
+                    assert(retList.get(0).getDocument() instanceof Activity);
+                    assertEquals(activity, retList.get(0).getDocument());
+                }
+            }
+        } catch (Exception e) {
+            LOGGER.error("Exception testing the GooglePlusTypeConverter: {}", e);
+        }
+    }
+
+    @Test
+    public void testEmptyProcess() {
+        List<StreamsDatum> retList = googlePlusTypeConverter.process(null);
+
+        assertEquals(retList.size(), 0);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/42d0ab33/streams-contrib/streams-provider-google/google-gplus/src/test/resources/google_plus_person_jsons.txt
----------------------------------------------------------------------
diff --git a/streams-contrib/streams-provider-google/google-gplus/src/test/resources/google_plus_person_jsons.txt b/streams-contrib/streams-provider-google/google-gplus/src/test/resources/google_plus_person_jsons.txt
index e69de29..3280747 100644
--- a/streams-contrib/streams-provider-google/google-gplus/src/test/resources/google_plus_person_jsons.txt
+++ b/streams-contrib/streams-provider-google/google-gplus/src/test/resources/google_plus_person_jsons.txt
@@ -0,0 +1,2 @@
+{"circledByCount":69,"displayName":"Robert Douglas","etag":"\"Vea_b94Y77GDGgRK7gFNPnolKQw/H7iVXOYgK9fQa4LWUIeauVGCMNE\"","gender":"male","id":"106406455118529211676","image":{"isDefault":false,"url":"https://lh3.googleusercontent.com/-u-IN7x710H8/AAAAAAAAAAI/AAAAAAAAAQE/tdo5WzJuBiM/photo.jpg?sz=50"},"isPlusUser":true,"kind":"plus#person","name":{"familyName":"Douglas","givenName":"Robert"},"objectType":"person","organizations":[{"name":"Johns Hopkins University","primary":true,"title":"Computer Science","type":"school"}],"url":"https://plus.google.com/106406455118529211676","verified":false}
+{ "kind": "plus#person", "etag": "\"Vea_b94Y77GDGgRK7gFNPnolKQw/_2kdKCZGyG8t19G4WeQrtqVZrHU\"", "gender": "male", "emails": [ { "value": "steve@blackmon.org", "type": "account" } ], "urls": [ { "value": "http://www.facebook.com/steveblackmon", "type": "otherProfile", "label": "steveblackmon" }, { "value": "http://twitter.com/steveblackmon", "type": "otherProfile", "label": "steveblackmon" }, { "value": "http://www.linkedin.com/in/blackmon", "type": "otherProfile", "label": "blackmon" }, { "value": "http://streams.incubator.apache.org/", "type": "contributor", "label": "Apache Streams" } ], "objectType": "person", "id": "118376908737486995861", "displayName": "Steve Blackmon", "name": { "familyName": "Blackmon", "givenName": "Steve" }, "tagline": "I am a talented hardware/software/systems engineer with a fervent interest in emerging technologies, and the economics of every imaginable industry sector.", "aboutMe": "<span>I enjoy thinking, reading, writing, coding, and communicating. M
 y passions are science, technology, business, their mutual coevolution, and their collective impact on society and economic development. I love traveling, meeting new people, being outdoors, and most cultural activities.<br /></span>", "url": "https://plus.google.com/+SteveBlackmon", "image": { "url": "https://lh3.googleusercontent.com/-XdUIqdMkCWA/AAAAAAAAAAI/AAAAAAAAAAA/4252rscbv5M/photo.jpg?sz=50", "isDefault": true }, "organizations": [ { "name": "McCombs School of Business", "title": "MBA", "type": "school", "endDate": "2013", "primary": false }, { "name": "University of Southern California", "title": "MS Computer Science", "type": "school", "endDate": "2005", "primary": false }, { "name": "University of Texas at Austin", "title": "BS Computer Engineering", "type": "school", "endDate": "2003", "primary": false }, { "name": "W2O Group", "title": "Director", "type": "work", "primary": true } ], "placesLived": [ { "value": "Austin, TX", "primary": true } ], "isPlusUser": true, "la
 nguage": "en", "circledByCount": 139, "verified": false, "domain": "blackmon.org" }
\ No newline at end of file