You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by mf...@apache.org on 2013/03/18 17:50:14 UTC

svn commit: r1457858 - in /rave/trunk: rave-components/rave-commons/src/main/java/org/apache/rave/exception/ rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/ rave-portal-resources/src/main/webapp/static/script/ rave-providers/rave-opensocial-pr...

Author: mfranklin
Date: Mon Mar 18 16:50:13 2013
New Revision: 1457858

URL: http://svn.apache.org/r1457858
Log:
Added metadata endpoint to opensocial rest service and refactored for maintainability (fixes RAVE-912)

Added:
    rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/exception/ResourceNotFoundException.java
Modified:
    rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/personProfile.jsp
    rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_opensocial.js
    rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/controller/SecurityTokenController.java
    rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/OpenSocialService.java
    rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/impl/DefaultOpenSocialService.java
    rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/test/java/org/apache/rave/provider/opensocial/service/OpenSocialServiceTest.java

Added: rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/exception/ResourceNotFoundException.java
URL: http://svn.apache.org/viewvc/rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/exception/ResourceNotFoundException.java?rev=1457858&view=auto
==============================================================================
--- rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/exception/ResourceNotFoundException.java (added)
+++ rave/trunk/rave-components/rave-commons/src/main/java/org/apache/rave/exception/ResourceNotFoundException.java Mon Mar 18 16:50:13 2013
@@ -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.rave.exception;
+
+/**
+ * Thrown when a required resource is not present
+ */
+public class ResourceNotFoundException extends RuntimeException {
+    public ResourceNotFoundException() {
+    }
+
+    public ResourceNotFoundException(String s) {
+        super(s);
+    }
+
+    public ResourceNotFoundException(String s, Throwable throwable) {
+        super(s, throwable);
+    }
+
+    public ResourceNotFoundException(Throwable throwable) {
+        super(throwable);
+    }
+    
+}

Modified: rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/personProfile.jsp
URL: http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/personProfile.jsp?rev=1457858&r1=1457857&r2=1457858&view=diff
==============================================================================
--- rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/personProfile.jsp (original)
+++ rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/personProfile.jsp Mon Mar 18 16:50:13 2013
@@ -203,6 +203,8 @@
     </div>
 <div class="clear-float">&nbsp;</div>
 
+<input id="currentPageId" type="hidden" value="${page.id}"/>
+
 <portal:register-init-script location="${'AFTER_RAVE'}">
     <script>
         $(function () {

Modified: rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_opensocial.js
URL: http://svn.apache.org/viewvc/rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_opensocial.js?rev=1457858&r1=1457857&r2=1457858&view=diff
==============================================================================
--- rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_opensocial.js (original)
+++ rave/trunk/rave-portal-resources/src/main/webapp/static/script/rave_opensocial.js Mon Mar 18 16:50:13 2013
@@ -106,10 +106,10 @@ rave.opensocial = rave.opensocial || (fu
             				var gadget = {
             			  	  "widgetUrl": widgetUrl,
             			  	  "securityToken": data.securityToken,
-            			  	  "metadata": opt_gadgetInfo
+            			  	  "metadata": gadgets.json.parse(data.metadata)
                             },
-                            height = data.metadata ? data.metadata.height : 500,
-                            width = data.metadata ? data.metadata.width : 525;
+                            height = gadget.metadata.modulePrefs.height ? gadget.metadata.modulePrefs.height : 500,
+                            width = gadget.metadata.modulePrefs.width ? gadget.metadata.modulePrefs.width : 525;
 
             				preloadMetadata(gadget);
                         
@@ -140,7 +140,7 @@ rave.opensocial = rave.opensocial || (fu
     function getSecurityToken(args) {
         $.ajax({
             type: 'GET',
-            url: rave.getContext() + "api/rest/" + "st?url=" + args.url + "&pageid=" + args.pageid,
+            url: rave.getContext() + "api/rest/opensocial/gadget?url=" + args.url + "&pageid=" + args.pageid,
             dataType: "json",
             success: function (data) {
                 if (typeof args.successCallback == 'function') {

Modified: rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/controller/SecurityTokenController.java
URL: http://svn.apache.org/viewvc/rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/controller/SecurityTokenController.java?rev=1457858&r1=1457857&r2=1457858&view=diff
==============================================================================
--- rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/controller/SecurityTokenController.java (original)
+++ rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/controller/SecurityTokenController.java Mon Mar 18 16:50:13 2013
@@ -19,72 +19,86 @@
 
 package org.apache.rave.provider.opensocial.controller;
 
-import org.apache.rave.portal.model.Page;
-import org.apache.rave.portal.model.RegionWidget;
-import org.apache.rave.portal.model.Widget;
-import org.apache.rave.portal.model.WidgetStatus;
-import org.apache.rave.portal.model.impl.RegionImpl;
-import org.apache.rave.portal.model.impl.RegionWidgetImpl;
-import org.apache.rave.portal.service.PageService;
-import org.apache.rave.portal.service.WidgetService;
-import org.apache.rave.provider.opensocial.exception.SecurityTokenException;
-import org.apache.rave.provider.opensocial.service.impl.EncryptedBlobSecurityTokenService;
+import com.google.common.collect.Maps;
+import org.apache.rave.exception.ResourceNotFoundException;
+import org.apache.rave.provider.opensocial.service.OpenSocialService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.util.HashMap;
 import java.util.Map;
 
 /**
  * Admin controller to manipulate Widget data
  */
-@Controller
-public class SecurityTokenController{
+@Controller @RequestMapping(value = "/api/rest/opensocial")
+public class SecurityTokenController {
+    private Logger logger = LoggerFactory.getLogger(getClass());
 
     @Autowired
-    private WidgetService widgetService;
-    
-    @Autowired
-    private PageService pageService;
-    
-    @Autowired
-    private EncryptedBlobSecurityTokenService securityTokenService;
+    private OpenSocialService openSocialService;
 
-    @RequestMapping(value = "/api/rest/st", method = RequestMethod.GET, produces="application/json")
+    @RequestMapping(value = "/gadget", method = RequestMethod.GET, produces="application/json")
     @ResponseBody
-    public Map<String, Object> getSecurityToken(@RequestParam("url") final String url, @RequestParam("pageid") final String pageId) {
-    	Widget widget = widgetService.getWidgetByUrl(url);
-    	Page page = pageService.getPage(pageId);
-    	
-    	// Use a dummy RegionWidget to generate the security token
-    	RegionWidget regionWidget = new RegionWidgetImpl(String.valueOf(System.currentTimeMillis()),"-1",
-    			new RegionImpl("-1", page, -1));
-    	
+    public Map<String, Object> getUnboundTokenAndMetadata(@RequestParam("url") final String url, @RequestParam("pageid") final String pageId) {
     	Map<String, Object> jsonResponse = new HashMap<String, Object>();
-    	Map<String, String> errorMessage = new HashMap<String, String>();
-    	
-    	String securityToken = "";
-    	if (widget != null && widget.getWidgetStatus() == WidgetStatus.PUBLISHED) {
-    		try {
-    			securityToken = securityTokenService.getEncryptedSecurityToken(regionWidget, widget);
-    		} catch (SecurityTokenException e) {
-    			errorMessage.put("message", "There was a problem creating the security token.");
-    		}
-    	} else if (widget != null && widget.getWidgetStatus() == WidgetStatus.PREVIEW) {
-    		errorMessage.put("message", "The requested gadget exists in the gadget store but is not published.");
-    	} else {
-    		errorMessage.put("message", "The requested gadget does not exist in the gadget store.");
-    	}
-    	
-    	jsonResponse.put("securityToken", securityToken);
-    	if (!errorMessage.isEmpty()) {
-    		jsonResponse.put("error", errorMessage);
-    	}
-    	
+        jsonResponse.put("securityToken", openSocialService.getEncryptedSecurityToken(pageId, url));
+        jsonResponse.put("metadata", openSocialService.getGadgetMetadata(url));
     	return jsonResponse;
     }
+
+    /**
+     * Return a 404 response code when any ResourceNotFoundException is thrown
+     *
+     * @param ex the ResourceNotFoundException
+     * @param request the http request
+     * @param response the http response
+     */
+    @ExceptionHandler(ResourceNotFoundException.class)
+    @ResponseBody
+    public Map<String, String> handleNotFound(Exception ex, HttpServletRequest request, HttpServletResponse response) {
+        return setResponse(ex, request, response, HttpStatus.NOT_FOUND);
+    }
+
+
+    /**
+     * Return a 400 response code when any IllegalState is thrown
+     *
+     * @param ex the IllegalStateException
+     * @param request the http request
+     * @param response the http response
+     */
+    @ExceptionHandler(IllegalStateException.class)
+    @ResponseBody
+    public Map<String, String> handleIllegalState(Exception ex, HttpServletRequest request, HttpServletResponse response) {
+        return setResponse(ex, request, response, HttpStatus.BAD_REQUEST);
+    }
+
+
+    /**
+     * Return a 500 response code when any unknown exception is thrown
+     *
+     * @param ex the exeption
+     * @param request the http request
+     * @param response the http response
+     */
+    @ExceptionHandler(Exception.class)
+    @ResponseBody
+    public Map<String, String> handleALl(Exception ex, HttpServletRequest request, HttpServletResponse response) {
+        return setResponse(ex, request, response, HttpStatus.INTERNAL_SERVER_ERROR);
+    }
+
+    private Map<String, String> setResponse(Exception ex, HttpServletRequest request, HttpServletResponse response, HttpStatus status) {
+        logger.error("Not Found Exception: " + request.getUserPrincipal().getName() + " attempted to access resource " + request.getRequestURI(), ex);
+        response.setStatus(status.value());
+        Map<String, String> errors = Maps.newHashMap();
+        errors.put("error", ex.getMessage());
+        return errors;
+    }
 }

Modified: rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/OpenSocialService.java
URL: http://svn.apache.org/viewvc/rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/OpenSocialService.java?rev=1457858&r1=1457857&r2=1457858&view=diff
==============================================================================
--- rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/OpenSocialService.java (original)
+++ rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/OpenSocialService.java Mon Mar 18 16:50:13 2013
@@ -27,4 +27,11 @@ public interface OpenSocialService {
      * @return The raw JSON response from the Shindig metadata RPC call.
      */
     String getGadgetMetadata(String gadgetUrl);
+
+    /**
+     * Gets a security token for a new instance (RegionWidget) of the given url
+     * @param widget the gadget URL to create a new instance for
+     * @return a valid, encrypted securityToken
+     */
+    String getEncryptedSecurityToken(String pageId, String widget);
 }
\ No newline at end of file

Modified: rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/impl/DefaultOpenSocialService.java
URL: http://svn.apache.org/viewvc/rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/impl/DefaultOpenSocialService.java?rev=1457858&r1=1457857&r2=1457858&view=diff
==============================================================================
--- rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/impl/DefaultOpenSocialService.java (original)
+++ rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/impl/DefaultOpenSocialService.java Mon Mar 18 16:50:13 2013
@@ -19,18 +19,34 @@
 
 package org.apache.rave.provider.opensocial.service.impl;
 
+import org.apache.rave.exception.ResourceNotFoundException;
+import org.apache.rave.portal.model.Page;
+import org.apache.rave.portal.model.RegionWidget;
+import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.WidgetStatus;
+import org.apache.rave.portal.model.impl.RegionImpl;
+import org.apache.rave.portal.model.impl.RegionWidgetImpl;
+import org.apache.rave.portal.service.PageService;
+import org.apache.rave.portal.service.WidgetService;
 import org.apache.rave.provider.opensocial.repository.GadgetMetadataRepository;
 import org.apache.rave.provider.opensocial.service.OpenSocialService;
+import org.apache.rave.provider.opensocial.service.SecurityTokenService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
 public class DefaultOpenSocialService implements OpenSocialService {
     private GadgetMetadataRepository gadgetMetadataRepository;
+    private final WidgetService widgetService;
+    private final PageService pageService;
+    private final SecurityTokenService tokenService;
 
     @Autowired
-    public DefaultOpenSocialService(GadgetMetadataRepository gadgetMetadataRepository) {
+    public DefaultOpenSocialService(GadgetMetadataRepository gadgetMetadataRepository, WidgetService widgetService, PageService pageService, SecurityTokenService tokenService) {
         this.gadgetMetadataRepository = gadgetMetadataRepository;
+        this.widgetService = widgetService;
+        this.pageService = pageService;
+        this.tokenService = tokenService;
     }
 
     @Override
@@ -38,4 +54,25 @@ public class DefaultOpenSocialService im
         //TODO RAVE-243 -- Add caching of gadget metadata in this service layer
         return gadgetMetadataRepository.getGadgetMetadata(gadgetUrl);
     }
+
+    @Override
+    public String getEncryptedSecurityToken(String pageId, String url) {
+        Widget widget = widgetService.getWidgetByUrl(url);
+        Page page = pageService.getPage(pageId);
+        validate(widget);
+        // Use a dummy RegionWidget to generate the security token
+        RegionWidget regionWidget = new RegionWidgetImpl(String.valueOf(System.currentTimeMillis()),"-1",
+                new RegionImpl("-1", page, -1));
+        String securityToken = "";
+        securityToken = tokenService.getEncryptedSecurityToken(regionWidget, widget);
+        return securityToken;
+    }
+
+    private void validate(Widget widget) {
+        if(widget == null) {
+            throw new ResourceNotFoundException("The requested gadget does not exist in the gadget store.");
+        } else if(widget.getWidgetStatus().equals(WidgetStatus.PREVIEW)) {
+            throw new IllegalStateException("The requested gadget exists in the gadget store but is not published.");
+        }
+    }
 }
\ No newline at end of file

Modified: rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/test/java/org/apache/rave/provider/opensocial/service/OpenSocialServiceTest.java
URL: http://svn.apache.org/viewvc/rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/test/java/org/apache/rave/provider/opensocial/service/OpenSocialServiceTest.java?rev=1457858&r1=1457857&r2=1457858&view=diff
==============================================================================
--- rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/test/java/org/apache/rave/provider/opensocial/service/OpenSocialServiceTest.java (original)
+++ rave/trunk/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/test/java/org/apache/rave/provider/opensocial/service/OpenSocialServiceTest.java Mon Mar 18 16:50:13 2013
@@ -19,20 +19,36 @@
 
 package org.apache.rave.provider.opensocial.service;
 
+import org.apache.rave.exception.ResourceNotFoundException;
+import org.apache.rave.portal.model.Page;
+import org.apache.rave.portal.model.RegionWidget;
+import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.WidgetStatus;
+import org.apache.rave.portal.model.impl.PageImpl;
+import org.apache.rave.portal.model.impl.WidgetImpl;
+import org.apache.rave.portal.service.PageService;
+import org.apache.rave.portal.service.WidgetService;
 import org.apache.rave.provider.opensocial.repository.GadgetMetadataRepository;
 import org.apache.rave.provider.opensocial.service.impl.DefaultOpenSocialService;
 import org.junit.Before;
 import org.junit.Test;
 
 import static org.easymock.EasyMock.*;
+import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.sameInstance;
 import static org.junit.Assert.assertThat;
 
 public class OpenSocialServiceTest {
+    public static final String VALID_TOKEN = "VALID_TOKEN";
     private OpenSocialService openSocialService;
     private GadgetMetadataRepository gadgetMetadataRepository;
+    private WidgetService widgetService;
+    private PageService pageService;
+    private SecurityTokenService tokenService;
 
+    private static final String VALID_PAGE_ID = "VALID";
+    private static final String VALID_OWNER_ID = "owner";
     private static final String VALID_GADGET_URL = "http://www.example.com/gadget.xml";
     private static final String VALID_METADATA = "[{\"id\":\"gadgets.metadata\",\"result\"" +
             ":{\"http://www.example.com/gadget.xml\":{\"data-snipped\":\"here-for-brevity\"}}}]";
@@ -40,7 +56,10 @@ public class OpenSocialServiceTest {
     @Before
     public void setup() {
         gadgetMetadataRepository = createNiceMock(GadgetMetadataRepository.class);
-        openSocialService = new DefaultOpenSocialService(gadgetMetadataRepository);
+        widgetService = createNiceMock(WidgetService.class);
+        pageService = createNiceMock(PageService.class);
+        tokenService = createNiceMock(SecurityTokenService.class);
+        openSocialService = new DefaultOpenSocialService(gadgetMetadataRepository, widgetService, pageService, tokenService);
     }
 
     @Test
@@ -51,4 +70,37 @@ public class OpenSocialServiceTest {
         String result = openSocialService.getGadgetMetadata(VALID_GADGET_URL);
         assertThat(result, is(sameInstance(VALID_METADATA)));
     }
+
+    @Test
+    public void getEncryptedSecurityToken_valid() {
+        Widget widget = new WidgetImpl("25", VALID_GADGET_URL);
+        Page page = new PageImpl(VALID_PAGE_ID, VALID_OWNER_ID);
+        widget.setWidgetStatus(WidgetStatus.PUBLISHED);
+        expect(widgetService.getWidgetByUrl(VALID_GADGET_URL)).andReturn(widget);
+        expect(pageService.getPage(VALID_PAGE_ID)).andReturn(page);
+        expect(tokenService.getEncryptedSecurityToken(isA(RegionWidget.class), eq(widget))).andReturn(VALID_TOKEN);
+        replay(widgetService, pageService, tokenService);
+
+        assertThat(openSocialService.getEncryptedSecurityToken(VALID_PAGE_ID, VALID_GADGET_URL), is(equalTo(VALID_TOKEN)));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void getEncryptedSecurityToken_NotPublished() {
+        Widget widget = new WidgetImpl("25", VALID_GADGET_URL);
+        widget.setWidgetStatus(WidgetStatus.PREVIEW);
+        expect(widgetService.getWidgetByUrl(VALID_GADGET_URL)).andReturn(widget);
+        replay(widgetService, pageService, tokenService);
+
+        assertThat(openSocialService.getEncryptedSecurityToken(VALID_PAGE_ID, VALID_GADGET_URL), is(equalTo(VALID_TOKEN)));
+    }
+
+    @Test(expected = ResourceNotFoundException.class)
+    public void getEncryptedSecurityToken_NotFound() {
+        Widget widget = new WidgetImpl("25", VALID_GADGET_URL);
+        widget.setWidgetStatus(WidgetStatus.PUBLISHED);
+        expect(widgetService.getWidgetByUrl(VALID_GADGET_URL)).andReturn(null);
+        replay(widgetService, pageService, tokenService);
+
+        assertThat(openSocialService.getEncryptedSecurityToken(VALID_PAGE_ID, VALID_GADGET_URL), is(equalTo(VALID_TOKEN)));
+    }
 }
\ No newline at end of file