/*
* Copyright 2013, 2014, 2015 EnergyOS.org
*
* Licensed 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.energyos.espi.thirdparty.web;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.stream.StreamSource;
import org.energyos.espi.common.domain.Authorization;
import org.energyos.espi.common.domain.BatchList;
import org.energyos.espi.common.domain.RetailCustomer;
import org.energyos.espi.common.domain.Routes;
import org.energyos.espi.common.service.AuthorizationService;
import org.energyos.espi.common.service.BatchListService;
import org.energyos.espi.common.service.ImportService;
import org.energyos.espi.common.service.ResourceService;
import org.energyos.espi.common.service.UsagePointService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.RestTemplate;
@Controller
public class NotificationController extends BaseController {
@Autowired
private BatchListService batchListService;
@Autowired
private ResourceService resourceService;
@Autowired
private UsagePointService usagePointService;
@Autowired
private ImportService importService;
@Autowired
private RestTemplate restTemplate;
@Autowired
private AuthorizationService authorizationService;
@Autowired
@Qualifier(value = "atomMarshaller")
public Jaxb2Marshaller marshaller;
@RequestMapping(value = Routes.THIRD_PARTY_NOTIFICATION, method = RequestMethod.POST)
public void notification(HttpServletResponse response,
InputStream inputStream) throws IOException {
BatchList batchList = (BatchList) marshaller
.unmarshal(new StreamSource(inputStream));
batchListService.persist(batchList);
for (String resourceUri : batchList.getResources()) {
doImportAsynchronously(resourceUri);
}
response.setStatus(HttpServletResponse.SC_OK);
}
@Async
private void doImportAsynchronously(String subscriptionUri) {
// The import related to a subscription is performed here (in a separate
// thread)
// This must be provably secure b/c the access_token is visible here
String threadName = Thread.currentThread().getName();
System.out.printf("Start Asynchronous Input: %s: %s\n ", threadName,
subscriptionUri);
String resourceUri = subscriptionUri;
String accessToken = "";
Authorization authorization = null;
RetailCustomer retailCustomer = null;
if (subscriptionUri.indexOf("?") > -1) { // Does message contain a query
// element
resourceUri = subscriptionUri.substring(0,
subscriptionUri.indexOf("?")); // Yes, remove the query
// element
}
if (resourceUri.contains("sftp://")) {
try {
String command = "sftp mget "
+ resourceUri.substring(resourceUri.indexOf("sftp://"));
System.out.println("[Manage] Restricted Management Interface");
System.out.println("[Manage] Request: " + command);
Process p = Runtime.getRuntime().exec(command);
// the sftp script will get the file and make a RESTful api call
// to add it into the workspace.
} catch (IOException e1) {
System.out.printf("**** [Manage] Error: %s\n", e1.toString());
} catch (Exception e) {
System.out.printf("**** [Manage] Error: %s\n", e.toString());
}
} else {
try {
if ((resourceUri.contains("/Batch/Bulk"))
|| (resourceUri.contains("/Authorization"))) {
// mutate the resourceUri to be of the form .../Batch/Bulk
resourceUri = (resourceUri.substring(
0,
resourceUri.indexOf("/resource/")
+ "/resource/".length())
.concat("Batch/Bulk"));
} else {
if (resourceUri.contains("/Subscription")) {
// mutate the resourceUri for the form
// /Subscription/{subscriptionId}/**
String temp = resourceUri.substring(resourceUri
.indexOf("/Subscription/")
+ "/Subscription/".length());
if (temp.contains("/")) {
resourceUri = resourceUri.substring(
0,
resourceUri.indexOf("/Subscription")
+ "/Subscription".length()).concat(
temp.substring(0, temp.indexOf("/")));
}
}
}
Authorization x = resourceService.findById(2L,
Authorization.class);
if (x.getResourceURI().equals(resourceUri)) {
System.out.println("ResourceURIs Equal:" + resourceUri);
} else {
System.out.println("ResourceURIs Not - Equal:"
+ resourceUri);
}
authorization = resourceService.findByResourceUri(resourceUri,
Authorization.class);
retailCustomer = authorization.getRetailCustomer();
accessToken = authorization.getAccessToken();
try {
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders
.set("Authorization", "Bearer " + accessToken);
@SuppressWarnings({ "unchecked", "rawtypes" })
HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);
// get the subscription
HttpEntity<String> httpResult = restTemplate.exchange(
subscriptionUri, HttpMethod.GET, requestEntity,
String.class);
// import it into the repository
ByteArrayInputStream bs = new ByteArrayInputStream(
httpResult.getBody().toString().getBytes());
importService.importData(bs, retailCustomer.getId());
} catch (Exception e) {
// Log exception so that issue can be investigated include
// stack trace to help locate issue
System.out
.printf("\nNotificationController -- Asynchronous Input:\n Cause = %s\n Description = %s\n\n",
e.getClass(), e.getMessage());
e.printStackTrace();
}
} catch (EmptyResultDataAccessException e) {
// No authorization, so log the fact and move on. It will
// get imported later
System.out
.printf("\nNotificationController -- Asynchronous Input:\n Cause = %s\n Description = %s\n\n",
e.getClass(), e.getMessage());
}
}
System.out.printf("Asynchronous Input Completed %s: %s\n", threadName,
resourceUri);
}
public void setBatchListService(BatchListService batchListService) {
this.batchListService = batchListService;
}
public void setImportService(ImportService importService) {
this.importService = importService;
}
public void setResourceService(ResourceService resourceService) {
this.resourceService = resourceService;
}
public void setUsagePointService(UsagePointService usagePointService) {
this.usagePointService = usagePointService;
}
public RestTemplate getRestTemplate() {
return this.restTemplate;
}
public void setMarshaller(Jaxb2Marshaller marshaller) {
this.marshaller = marshaller;
}
}