All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.butor.json.service.BaseServiceCaller Maven / Gradle / Ivy

Go to download

This module enables fast and easy creation of sync., async., req./resp., req./resp. stream HTTP/json services.

There is a newer version: 1.0.31
Show newest version
/**
 * Copyright 2013-2019 Butor Inc.
 *
 * 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.butor.json.service;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.Set;
import java.util.UUID;

import org.butor.json.JsonHelper;
import org.butor.json.JsonServiceRequest;
import org.butor.json.StreamHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.api.client.http.AbstractHttpContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpContent;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.util.Strings;

public abstract class BaseServiceCaller implements ServiceCaller {
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	private JsonHelper jsh = new JsonHelper();
	private String namespace;
	private String url;
	private int requestReadTimeout = 20  * 1000; // 20 seconds

	private int maxPayloadLengthToLog = -1;
	private Set servicesToNotLogArgs = Collections.emptySet();

	private boolean doMultiPartRequest = false;

	private HttpTransport HTTP_TRANSPORT  = new NetHttpTransport();
	private HttpRequestFactory requestFactory = HTTP_TRANSPORT
			.createRequestFactory(new HttpRequestInitializer() {
				@Override
				public void initialize(HttpRequest request) {							
				}
			});
	
	public BaseServiceCaller(String namespace, String url) {
		this.namespace = namespace;
		this.url = url;
		logger.info(String.format("Created service caller: namespace=%s, url=%s", 
				this.namespace, this.url));
	}
	public void setMaxPayloadLengthToLog(int maxPayloadLengthToLog) {
		this.maxPayloadLengthToLog = maxPayloadLengthToLog;
	}
	public String serialize(Object args) {
		return jsh.serialize(args);
	}
	public JsonServiceRequest createRequest(String service,
			Object serviceArgs, String userId, String sessionId, String reqId) {
		JsonServiceRequest req = new JsonServiceRequest();
		if (Strings.isNullOrEmpty(sessionId)) {
			sessionId = "session-" +UUID.randomUUID().toString();
		}
		req.setSessionId(sessionId);
		if (Strings.isNullOrEmpty(reqId)) {
			reqId = "request-" +UUID.randomUUID().toString();
		}
		req.setReqId(reqId);
		req.setUserId(userId);
		req.setNamespace(this.namespace);
		req.setService(service);
		req.setServiceArgsJson(serviceArgs instanceof String ? 
				(String)serviceArgs : serialize(serviceArgs));

		return req;
	}
	@Override
	public void call(final JsonServiceRequest jsonServiceRequest,
			final ResponseHandler handler) throws ServiceCallException {

		long time = System.currentTimeMillis();
		boolean success = false;

		try {
			final GenericUrl url = new GenericUrl(this.url);

			HttpContent hc = getHttpContent(jsonServiceRequest, handler, url);

			HttpRequest request = requestFactory.buildPostRequest(url, hc);
			request.setReadTimeout(requestReadTimeout);
			HttpResponse resp = request.execute();
			InputStream is = resp.getContent();
			String reqLogInfo = String.format("reqId: %s, sessionId: %s",
					jsonServiceRequest.getReqId(), jsonServiceRequest.getSessionId());
			StreamHandler jsh = getStreamHandler();
			jsh.parse(is, handler, reqLogInfo);
			success = true;
		} catch (IOException e) {
			throw new ServiceCallException(e);
		} finally {
			String namespace = jsonServiceRequest.getNamespace();
			String service = jsonServiceRequest.getService();
			String reqId = jsonServiceRequest.getReqId();
			String sessionId = jsonServiceRequest.getSessionId();
			String userId = jsonServiceRequest.getUserId();
			long elapsed = System.currentTimeMillis() - time;
			Object[] args = new Object[] { namespace, service, reqId, sessionId, userId, Boolean.valueOf(success), Long.valueOf(elapsed), url };
			logger.info("Service: STATS namespace: {}, service: {}, reqId: {}, sessionId: {}, userId: {}, success: {}, elapsed: {} ms, url: {}", args);
			// When HttpClient instance is no longer needed,
		}
	}
	
	protected HttpContent getHttpContent(final JsonServiceRequest jsonServiceRequest, final ResponseHandler handler, final GenericUrl url){
		return getAbstractHttpContent(jsonServiceRequest, url);
	}
	
	protected AbstractHttpContent getAbstractHttpContent(final JsonServiceRequest jsonServiceRequest, final GenericUrl url) {
		return new AbstractHttpContent("text/json") {

			String content = serialize(jsonServiceRequest);

			@Override
			public long getLength() throws IOException {
				return content.getBytes("utf-8").length;
			}

			@Override
			public void writeTo(OutputStream out_) throws IOException {
				boolean logArgs = !servicesToNotLogArgs.contains(jsonServiceRequest.getService());
				String logInfo = "";
				if (logArgs) {
					if (maxPayloadLengthToLog < 0 || content.length() <= maxPayloadLengthToLog) {
						logInfo = content.toString();
					} else {
						if (logger.isDebugEnabled()) {
							logInfo = content.toString();
						} else {
							String service = String.format("service: %s%s, reqId: %s, sessionId: %s, userId: %s", url, jsonServiceRequest.getService(),
									jsonServiceRequest.getReqId(), jsonServiceRequest.getSessionId(), jsonServiceRequest.getUserId());

							int argsLen = content.length();
							String chunck = content.substring(0, maxPayloadLengthToLog);
							logInfo = String.format("%s, payload: %s... %d chars (truncated - full content in debug level)", service, chunck, argsLen);
						}
					}
				} else {
					String service = String.format("service: %s%s, reqId: %s, sessionId: %s, userId: %s", url, jsonServiceRequest.getService(), jsonServiceRequest.getReqId(),
							jsonServiceRequest.getSessionId(), jsonServiceRequest.getUserId());
					logInfo = String.format("%s, payload: /*censored*/", service);
				}
				logger.info(String.format("Calling %s on url:%s ...", logInfo, url));
				out_.write(content.getBytes("utf-8"));
				out_.flush();
			}
		};
	}
	
	protected abstract StreamHandler getStreamHandler();

	public void setServicesToNotLogArgs(Set servicesToNotLogArgs) {
		this.servicesToNotLogArgs = servicesToNotLogArgs;
		if (this.servicesToNotLogArgs == null) {
			this.servicesToNotLogArgs = Collections.emptySet();
		}
	}
	
	public void setRequestReadTimeout(int requestReadTimeout) {
		this.requestReadTimeout = requestReadTimeout;
	}
	public void setDoMultiPartRequest(boolean doMultiPartRequest) {
		this.doMultiPartRequest = doMultiPartRequest;
	}
	public boolean isDoMultiPartRequest() {
		return doMultiPartRequest;
	}	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy