github.com/cs3org/reva/v2@v2.27.7/pkg/ocm/share/sender/sender.go (about)

     1  // Copyright 2018-2023 CERN
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  package sender
    20  
    21  import (
    22  	"context"
    23  	"encoding/json"
    24  	"fmt"
    25  	"io"
    26  	"net/http"
    27  	"net/url"
    28  	"path"
    29  	"strings"
    30  	"time"
    31  
    32  	ocmprovider "github.com/cs3org/go-cs3apis/cs3/ocm/provider/v1beta1"
    33  	"github.com/cs3org/reva/v2/pkg/appctx"
    34  	"github.com/cs3org/reva/v2/pkg/rhttp"
    35  	"github.com/pkg/errors"
    36  )
    37  
    38  const createOCMCoreShareEndpoint = "shares"
    39  
    40  func getOCMEndpoint(originProvider *ocmprovider.ProviderInfo) (string, error) {
    41  	for _, s := range originProvider.Services {
    42  		if s.Endpoint.Type.Name == "OCM" {
    43  			return s.Endpoint.Path, nil
    44  		}
    45  	}
    46  	return "", errors.New("json: ocm endpoint not specified for mesh provider")
    47  }
    48  
    49  // Send executes the POST to the OCM shares endpoint to create the share at the
    50  // remote site.
    51  func Send(ctx context.Context, requestBodyMap map[string]interface{}, pi *ocmprovider.ProviderInfo) error {
    52  	requestBody, err := json.Marshal(requestBodyMap)
    53  	if err != nil {
    54  		err = errors.Wrap(err, "error marshalling request body")
    55  		return err
    56  	}
    57  	ocmEndpoint, err := getOCMEndpoint(pi)
    58  	if err != nil {
    59  		return err
    60  	}
    61  	u, err := url.Parse(ocmEndpoint)
    62  	if err != nil {
    63  		return err
    64  	}
    65  	u.Path = path.Join(u.Path, createOCMCoreShareEndpoint)
    66  	recipientURL := u.String()
    67  
    68  	log := appctx.GetLogger(ctx)
    69  	log.Info().Msgf("in OCM Send! %s %s", recipientURL, requestBody)
    70  
    71  	req, err := http.NewRequest(http.MethodPost, recipientURL, strings.NewReader(string(requestBody)))
    72  	if err != nil {
    73  		return errors.Wrap(err, "sender: error framing post request")
    74  	}
    75  	req.Header.Set("Content-Type", "application/json")
    76  	client := rhttp.GetHTTPClient(
    77  		rhttp.Timeout(5 * time.Second),
    78  	)
    79  
    80  	resp, err := client.Do(req)
    81  	if err != nil {
    82  		err = errors.Wrap(err, "sender: error sending post request")
    83  		return err
    84  	}
    85  
    86  	defer resp.Body.Close()
    87  	if (resp.StatusCode != http.StatusCreated) && (resp.StatusCode != http.StatusOK) {
    88  		respBody, e := io.ReadAll(resp.Body)
    89  		if e != nil {
    90  			e = errors.Wrap(e, "sender: error reading request body")
    91  			return e
    92  		}
    93  		err = errors.Wrap(fmt.Errorf("%s: %s", resp.Status, string(respBody)), "sender: error from "+ocmEndpoint)
    94  		return err
    95  	}
    96  	return nil
    97  }