Как я могу создавать и проверять веб-хуки для onedrive или sharepoint онлайн? - PullRequest
0 голосов
/ 16 апреля 2019

Я хочу подписку на мою папку OneDrive. После успешной авторизации и получения токена доступа для моего OneDrive я могу работать со всеми своими папками и файлами в OneDrive. Но мне не удается создать подписку.

Я реализую загрузочное приложение Java Spring, которое уже развернуто в Azure и доступно, например, по адресу: https://{tenant}.westeurope.cloudapp.azure.com/api

Когда я пытаюсь создать подписку, я получаю код ответа: 400 с сообщением: «Запрос проверки не выполнен. Необходимо ответить 200 OK на этот запрос».

Прочитав всю замечательную документацию , я не смог найти решение своей проблемы. Может быть, я неправильно понял некоторые общие настройки.

Это мои конечные точки:

@RestController
@CrossOrigin
public class OneDriveSubscriptionsController {

    @Autowired
    private SubscriptionService subscriptionService;

    // Should be used to create a subscription
    @RequestMapping(method=RequestMethod.GET, value="/create")
    public ResponseEntity<?> create() {

        OneDriveSubscriptionVO subscription = new OneDriveSubscriptionVO();
        oneDriveSubscriptionService.createSubscription(subscription);
        return new ResponseEntity<String>("", HttpStatus.OK);
    }

    // Should be used to validate a subscription
    @RequestMapping(method=RequestMethod.POST, value="/create")
    public ResponseEntity<?> validation(@RequestParam String validationtoken) {

        ResponseEntity<String> response = new ResponseEntity<String>(validationtoken, HttpStatus.OK);
        return response;
    }

    // Should be used to receive notification's.
    @RequestMapping(method=RequestMethod.POST, value="/notification" consumes=MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> subscriptionUpdate(@RequestBody OneDriveSubscriptionVO subscription) {
        // working with received notifications.
    }
}

Мой класс обслуживания:

@Service
public class SubscriptionService {

    public synchronized String create(OneDriveSubscriptionVO subscription) {
        String url = "https://graph.microsoft.com/v1.0/subscriptions";
        String authorization = "Bearer "+AccessInformation.getAccess_token();
        HttpClient httpclient = HttpClients.createDefault();
        String ret = null;

            try {
                URIBuilder builder = new URIBuilder(url);
                URI uri = builder.build();

                String serialisedJsonString = Util.serializeJson(subscription); 
                StringEntity entity = new StringEntity(serialisedJsonString);

                HttpPost request = new HttpPost(uri);
                request.setEntity(entity);
                request.setHeader("Authorization", authorization);
                request.setHeader("Content-Type", "application/json");

                HttpResponse response = httpclient.execute(request);
                HttpEntity responseEntity = response.getEntity();

                ret = EntityUtils.toString(responseEntity);

        } catch (Exception e) {
            logger.error(e.getMessage());
        }

        return ret;
    }
}

Мой класс помощников:

public class Util {
    private <T>String serializeJson(T obj) {
        Gson gson;
        GsonBuilder builder = new GsonBuilder(); 
        builder.setPrettyPrinting(); 
        gson = builder.create(); 
        return gson.toJson(obj);
    }
}

Мой класс OneDriveSubscriptionVO (упрощенный):

@JsonIgnoreProperties(ignoreUnknown = true)
public class OneDriveSubscriptionVO {

    private String id;
    private String clientState;
    private String expirationDateTime;
    private String notificationUrl;
    private String resource;
    private String changeType;

    public OneDriveSubscriptionVO() {
        this.clientState = "random string";
        this.expirationDateTime = "2019-05-15T11:23:00.000Z";
        this.notificationUrl= "https://{tenant}.westeurope.cloudapp.azure.com/api/notification";
        this.resource = "/me/drive/root";
        this.changeType = "updated";
    }

Насколько я знаю, мне нужно создать подписку с данными из моего конструктора OneDriveSubscriptionVO. В течение 5 секунд я должен ответить с полученным токеном проверки.

После отправки данных о создании я получаю сообщение об ошибке «Запрос на проверку не выполнен. Необходимо ответить 200 OK на этот запрос». и нет знака проверки для включения подписки.

Это json, который я хочу использовать для создания подписки:

{
  "clientState": "random string",
  "expirationDateTime": "2019-05-15T11:23:00.000Z",
  "notificationUrl": "https://{tenant}.cloudapp.azure.com/onedrive/api/notification",
  "resource": "/me/drive/root",
  "changeType": "updated"
}

Вот что я получаю:

{
  "error": {
    "code": "InvalidRequest",
    "message": "Subscription validation request failed. Must respond with 200 OK to this request.",
    "innerError": {
      "request-id": "5bf8a5e2-efd4-4863-bdc3-1fb7c89afa83",
      "date": "2019-04-16T11:43:58"
    }
  }
}

Я думаю, что, как правило, что-то не так, потому что ни одна конечная точка не сработала после моего "запроса POST создания подписки".

1 Ответ

0 голосов
/ 16 апреля 2019

Запрос на проверку отправляется той же конечной точке, что и уведомления. Похоже, вы ожидаете, что проверка будет выполнена для /create, а конечная точка, указанная для уведомлений, - /notification. Вы захотите объединить реализацию POST-to- / create с уведомлением POST-to- /. Вот пример функции Azure, которая даст вам представление о том, как это выглядит:

#r "Newtonsoft.Json"
 
using System;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using Newtonsoft.Json;
 
public static async Task<object> Run(HttpRequestMessage request, TraceWriter log)
{
    var content = await request.Content.ReadAsStringAsync();

    var query = request.RequestUri.Query
        .TrimStart('?')
        .Split('&')
        .Where(x => !String.IsNullOrEmpty(x))
        .Select(x => x.Split('='))
        .ToDictionary(x => x[0], x => Uri.UnescapeDataString(x[1]).Replace("+", " "), StringComparer.OrdinalIgnoreCase)
        ?? new Dictionary<string,string>();

    string token;

    if (query.TryGetValue("validationToken", out token))
    {
        var response = request.CreateResponse(HttpStatusCode.OK);
        response.Content = new StreamContent(new MemoryStream(Encoding.UTF8.GetBytes(token)));
        return response;
    }
 
    return request.CreateResponse(HttpStatusCode.OK, "Done!");
}
...