001/** 002 * Copyright (C) 2006-2024 Talend Inc. - www.talend.com 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.talend.sdk.component.runtime.manager.service.http; 017 018import static java.util.stream.Collectors.toMap; 019 020import java.util.Collection; 021import java.util.Map; 022import java.util.Optional; 023import java.util.function.BiFunction; 024import java.util.function.Function; 025 026import org.talend.sdk.component.api.service.http.Configurer; 027 028import lombok.AllArgsConstructor; 029import lombok.Data; 030import lombok.EqualsAndHashCode; 031 032@Data 033@AllArgsConstructor() 034@EqualsAndHashCode(exclude = "bodyCache") 035public class HttpRequest { 036 037 private static final Object[] EMPTY_ARRAY = new Object[0]; 038 039 private static final Configurer.ConfigurerConfiguration EMPTY_CONFIGURER_OPTIONS = 040 new Configurer.ConfigurerConfiguration() { 041 042 @Override 043 public Object[] configuration() { 044 return EMPTY_ARRAY; 045 } 046 047 @Override 048 public <T> T get(final String name, final Class<T> type) { 049 return null; 050 } 051 }; 052 053 private final String url; 054 055 private final String methodType; 056 057 private final Collection<String> queryParams; 058 059 private final Map<String, String> headers; 060 061 private final Configurer configurer; 062 063 private final Map<String, Function<Object[], Object>> configurerOptions; 064 065 private final BiFunction<String, Object[], Optional<byte[]>> payloadProvider; 066 067 private final Object[] params; 068 069 private volatile Optional<byte[]> bodyCache; 070 071 /** 072 * encode payload only when requested 073 * 074 * @return bytes encoded payload 075 */ 076 public Optional<byte[]> getBody() { 077 if (bodyCache != null) { 078 return bodyCache; 079 } 080 synchronized (this) { 081 if (bodyCache != null) { 082 return bodyCache; 083 } 084 return bodyCache = doGetBody(); 085 } 086 } 087 088 private Optional<byte[]> doGetBody() { 089 if (payloadProvider == null) { 090 return Optional.empty(); 091 } 092 return payloadProvider.apply(headers.get("content-type"), params); 093 } 094 095 public Configurer.ConfigurerConfiguration getConfigurationOptions() { 096 final Map<String, Object> options = configurerOptions 097 .entrySet() 098 .stream() 099 .collect(toMap(Map.Entry::getKey, e -> e.getValue().apply(params))); 100 101 return configurerOptions.isEmpty() ? EMPTY_CONFIGURER_OPTIONS : new Configurer.ConfigurerConfiguration() { 102 103 @Override 104 public Object[] configuration() { 105 return options.values().toArray(new Object[0]); 106 } 107 108 @Override 109 public <T> T get(final String name, final Class<T> type) { 110 return type.cast(options.get(name)); 111 } 112 }; 113 } 114}