001/*
002 * #%L
003 * HAPI FHIR JAX-RS Server
004 * %%
005 * Copyright (C) 2014 - 2024 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.jaxrs.client;
021
022import ca.uhn.fhir.i18n.Msg;
023import ca.uhn.fhir.rest.api.RequestTypeEnum;
024import ca.uhn.fhir.rest.client.api.BaseHttpRequest;
025import ca.uhn.fhir.rest.client.api.IHttpRequest;
026import ca.uhn.fhir.rest.client.api.IHttpResponse;
027import ca.uhn.fhir.util.StopWatch;
028import jakarta.ws.rs.client.Entity;
029import jakarta.ws.rs.client.Invocation;
030import jakarta.ws.rs.core.Response;
031
032import java.util.Collections;
033import java.util.HashMap;
034import java.util.LinkedList;
035import java.util.List;
036import java.util.Map;
037
038/**
039 * A Http Request based on JaxRs. This is an adapter around the class
040 * {@link jakarta.ws.rs.client.Invocation Invocation}
041 *
042 * @author Peter Van Houte | peter.vanhoute@agfa.com | Agfa Healthcare
043 */
044public class JaxRsHttpRequest extends BaseHttpRequest implements IHttpRequest {
045
046        private final Map<String, List<String>> myHeaders = new HashMap<>();
047        private Invocation.Builder myRequest;
048        private RequestTypeEnum myRequestType;
049        private Entity<?> myEntity;
050
051        public JaxRsHttpRequest(Invocation.Builder theRequest, RequestTypeEnum theRequestType, Entity<?> theEntity) {
052                this.myRequest = theRequest;
053                this.myRequestType = theRequestType;
054                this.myEntity = theEntity;
055        }
056
057        @Override
058        public void addHeader(String theName, String theValue) {
059                if (!myHeaders.containsKey(theName)) {
060                        myHeaders.put(theName, new LinkedList<>());
061                }
062                myHeaders.get(theName).add(theValue);
063                getRequest().header(theName, theValue);
064        }
065
066        @Override
067        public IHttpResponse execute() {
068                StopWatch responseStopWatch = new StopWatch();
069                Invocation invocation = getRequest().build(getRequestType().name(), getEntity());
070                Response response = invocation.invoke();
071                return new JaxRsHttpResponse(response, responseStopWatch);
072        }
073
074        @Override
075        public Map<String, List<String>> getAllHeaders() {
076                return Collections.unmodifiableMap(this.myHeaders);
077        }
078
079        /**
080         * Get the Entity
081         *
082         * @return the entity
083         */
084        public Entity<?> getEntity() {
085                return myEntity;
086        }
087
088        @Override
089        public String getHttpVerbName() {
090                return myRequestType.name();
091        }
092
093        @Override
094        public void removeHeaders(String theHeaderName) {
095                myHeaders.remove(theHeaderName);
096        }
097
098        /**
099         * Get the Request
100         *
101         * @return the Request
102         */
103        public Invocation.Builder getRequest() {
104                return myRequest;
105        }
106
107        @Override
108        public String getRequestBodyFromStream() {
109                // not supported
110                return null;
111        }
112
113        /**
114         * Get the Request Type
115         *
116         * @return the request type
117         */
118        public RequestTypeEnum getRequestType() {
119                return myRequestType == null ? RequestTypeEnum.GET : myRequestType;
120        }
121
122        @Override
123        public String getUri() {
124                return ""; // TODO: can we get this from somewhere?
125        }
126
127        @Override
128        public void setUri(String theUrl) {
129                throw new UnsupportedOperationException(Msg.code(606));
130        }
131}