Commit c69ba15b authored by Marco Descher's avatar Marco Descher
Browse files

[16515] Refactor IMessageService and dependents

parent cf3e8f45
Loading
Loading
Loading
Loading
+20 −15
Original line number Diff line number Diff line
package ch.elexis.core.services;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.osgi.service.component.annotations.Component;

import ch.elexis.core.model.IMessage;
@@ -18,25 +19,29 @@ public class InternalDatabaseMessageTransporter implements IMessageTransporter {
	public IStatus send(TransientMessage message){
		
		IMessage idbMessage = CoreModelServiceHolder.get().create(IMessage.class);
		// TODO copy all
		
//		IMessage persistedMessage = CoreModelServiceHolder.get().create(IMessage.class);
		idbMessage.setSender(message.getSender());
		idbMessage.setMessageText(message.getMessageText());
		idbMessage.setMessageCodes(message.getMessageCodes());
		idbMessage.setMessagePriority(message.getMessagePriority());
		idbMessage.setCreateDateTime(message.getCreateDateTime());
		idbMessage.setSenderAcceptsAnswer(message.isSenderAcceptsAnswer());
		
		boolean save = CoreModelServiceHolder.get().save(idbMessage);
		if (save) {
			return Status.OK_STATUS;
		}
		
//		boolean result = CoreModelServiceHolder.get().save(message);
//		if(result) {
//			return Status.OK_STATUS;
//		}
		return ObjectStatus.ERROR_STATUS(message.getId());
		return ObjectStatus.ERROR_STATUS(idbMessage.getId());
	}
	
	@Override
	public int getDefaultPriority(){
		return 0;
	public String getUriScheme(){
		return "internaldb";
	}
	
	@Override
	public String getId(){
		return "internaldatabase";
		public boolean isExternal(){
			return false;
		}

}
+46 −61
Original line number Diff line number Diff line
package ch.elexis.core.services;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.slf4j.LoggerFactory;

import ch.elexis.core.model.IUser;
import ch.elexis.core.model.message.TransientMessage;
import ch.elexis.core.services.holder.CoreModelServiceHolder;
import ch.elexis.core.status.StatusUtil;
import ch.elexis.core.services.internal.Bundle;
import ch.elexis.core.status.ObjectStatus;

@Component
public class MessageService implements IMessageService {
	
	@Reference
	private IContextService contextService;
	
	/**
	 * all transporters available
	 */
	private List<IMessageTransporter> messageTransporters;
	/**
	 * transporters considered for default message transportation
	 */
	private List<IMessageTransporter> defaultTransporters;
	private Map<String, IMessageTransporter> messageTransporters;
	
	public MessageService(){
		messageTransporters = new ArrayList<>();
		defaultTransporters = new ArrayList<>();
		messageTransporters = new HashMap<>();
	}
	
	@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY)
	public void setMessageTransporter(IMessageTransporter messageTransporter){
		if (!messageTransporters.contains(messageTransporter)) {
			messageTransporters.add(messageTransporter);
			if (messageTransporter.getDefaultPriority() >= 0) {
				defaultTransporters.add(messageTransporter);
			}
			Collections.sort(defaultTransporters);
		if (!messageTransporters.containsKey(messageTransporter.getUriScheme())) {
			messageTransporters.put(messageTransporter.getUriScheme(), messageTransporter);
		}
	}
	
	public void unsetMessageTransporter(IMessageTransporter messageTransporter){
		if (messageTransporters.contains(messageTransporter)) {
			messageTransporters.remove(messageTransporter);
			if (messageTransporter.getDefaultPriority() >= 0) {
				defaultTransporters.remove(messageTransporter);
			}
			Collections.sort(defaultTransporters);
		if (messageTransporters.containsKey(messageTransporter.getUriScheme())) {
			messageTransporters.remove(messageTransporter.getUriScheme());
		}
	}
	
	@Override
	public TransientMessage prepare(String sender, String... receiver){
		boolean senderIsUser = CoreModelServiceHolder.get().load(sender, IUser.class).isPresent();
		return new TransientMessage(sender, senderIsUser, receiver);
	public TransientMessage prepare(String sender, String receiver){
		return new TransientMessage(sender, receiver);
	}
	
	@Override
	public TransientMessage prepare(IUser sender, String... receiver){
		return new TransientMessage(sender.getId(), true, receiver);
	public List<String> getSupportedUriSchemes(){
		return new ArrayList<String>(messageTransporters.keySet());
	}
	
	@Override
	public List<IMessageTransporter> getAvailableTransporters(){
		return new ArrayList<IMessageTransporter>(messageTransporters);
	}
	public ObjectStatus send(TransientMessage message){
		
	@Override
	public IStatus send(TransientMessage message){
		List<IMessageTransporter> consideredTransporters;
		List<String> preferredTransporters = message.getPreferredTransporters();
		if (preferredTransporters.isEmpty()) {
			consideredTransporters = defaultTransporters;
		} else {
			consideredTransporters = new ArrayList<>();
			// TODO populate
		String receiver = message.getReceiver();
		int indexOf = receiver.indexOf(':');
		if (indexOf <= 0) {
			return new ObjectStatus(Status.ERROR, Bundle.ID,
				"No transporter uri scheme found in receiver [" + receiver + "]", null);
		}
		
		IStatus status = null;
		for (IMessageTransporter messageTransporter : consideredTransporters) {
			status = messageTransporter.send(message);
			if (status.isOK()) {
				return status;
		String uriScheme = receiver.substring(0, indexOf);
		IMessageTransporter messageTransporter = null;
		if (uriScheme.equals(INTERNAL_MESSAGE_URI_SCHEME)) {
			messageTransporter = selectInternalSchemeTransporter();
		} else {
				StatusUtil.logStatus(LoggerFactory.getLogger(getClass()), status);
			messageTransporter = messageTransporters.get(uriScheme);
		}
			// if CANCEL or ERROR continue
		
		if (messageTransporter == null) {
			return new ObjectStatus(Status.ERROR, Bundle.ID,
				"No transporter found for uri scheme found  [" + uriScheme + "]", null);
		}
		
		if (status == null) {
			status = new Status(Status.ERROR, "", "No message transporter found");
		return new ObjectStatus(messageTransporter.send(message),
			messageTransporter.getUriScheme());
	}
	
		return status;
	/**
	 * Select a transporter for an internal message. Currently we prefer the rocketchat transporter
	 * (if available).
	 * 
	 * @return the transporter or <code>null</code> if none available
	 */
	private IMessageTransporter selectInternalSchemeTransporter(){
		IMessageTransporter messageTransporter = messageTransporters.get("rocketchat");
		if (messageTransporter == null) {
			messageTransporter = messageTransporters.get("internaldb");
		}
		return messageTransporter;
	}
	
}
+22 −22
Original line number Diff line number Diff line
@@ -7,7 +7,9 @@ import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
@@ -19,6 +21,7 @@ import ch.elexis.core.eenv.IElexisEnvironmentService;
import ch.elexis.core.model.message.TransientMessage;
import ch.elexis.core.services.IContextService;
import ch.elexis.core.services.IMessageTransporter;
import ch.elexis.core.services.internal.Bundle;

@Component
public class RocketchatMessageTransporter implements IMessageTransporter {
@@ -36,30 +39,20 @@ public class RocketchatMessageTransporter implements IMessageTransporter {
	private IContextService contextService;
	
	@Override
	public int getDefaultPriority(){
		return 10;
	public String getUriScheme(){
		return "rocketchat";
	}
	
	@Override
	public String getId(){
		return "rocketchat";
	public boolean isExternal(){
		return false;
	}
	
	@Override
	public IStatus send(TransientMessage message){
		if (message.isSenderIsUser()) {
			return sendFromUserSender(message);
		}
		
		return sendFromStationSender(message);
	}
	
	private IStatus sendFromUserSender(TransientMessage message){
		// TODO where to get integrationtoken from? what if we are user - not elexis-server?
		// is the user logged in to rocketchat?
		return new Status(Status.ERROR, "", "Not yet implemented");
	}
	
	private IStatus sendFromStationSender(TransientMessage message){
		Optional<String> authorizationToken = contextService
			.getNamed(CTX_ROCKETCHAT_STATION_INTEGRATION_TOKEN).map(e -> e.toString());
@@ -73,24 +66,30 @@ public class RocketchatMessageTransporter implements IMessageTransporter {
				return send(integrationUrl, jsonMessage.getBytes());
				
			} catch (IOException e) {
				e.printStackTrace();
				return new Status(Status.ERROR, Bundle.ID, e.getMessage());
			}
		}
		
		return new Status(Status.ERROR, "",
		return new Status(Status.ERROR, Bundle.ID,
			"No webhook integration token [" + CTX_ROCKETCHAT_STATION_INTEGRATION_TOKEN
				+ "] found in root context or malformed url.");
	}
	
	private String prepareRocketchatMessage(TransientMessage message){
		JSONObject json = new JSONObject();
		json.put("username", contextService.getStationIdentifier());
		json.put("username", message.getSender());
		
		StringBuilder header = new StringBuilder();
		message.getReceiver().forEach(c -> header.append("@" + c + " "));
		header
			.append("@" + message.getReceiver().substring(message.getReceiver().indexOf(':') + 1));
		
		Set<Entry<String, String>> entrySet = message.getMessageCodes().entrySet();
		if (!entrySet.isEmpty()) {
			header.append(" | ");
			message.getMessageCodes().entrySet()
				.forEach(c -> header.append(c.getKey() + ":" + c.getValue() + " "));
		}
		
		json.put("text", header.toString());
		
		Map<String, Object> params = new HashMap<>();
@@ -116,7 +115,8 @@ public class RocketchatMessageTransporter implements IMessageTransporter {
		if (responseCode == 200) {
			return Status.OK_STATUS;
		}
		return new Status(Status.ERROR, "", "Error sending, with response code: " + responseCode);
		return new Status(Status.ERROR, Bundle.ID,
			"Error sending, with response code: " + responseCode);
	}
	
}
+5 −0
Original line number Diff line number Diff line
package ch.elexis.core.services.internal;

public class Bundle {
	public static final String ID = "ch.elexis.core.services";
}
+3 −3
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.elexis.core.model.IMessage;
import ch.elexis.core.model.IUser;
import ch.elexis.core.model.message.MessageCode;
import ch.elexis.core.model.message.TransientMessage;
@@ -275,8 +274,9 @@ public class TaskServiceImpl implements ITaskService {
	}
	
	private void sendMessageToOwner(ITask task, IUser owner, TaskState state){
		TransientMessage message = messageService
			.prepare(contextService.getRootContext().getStationIdentifier(), owner.getId());
		TransientMessage message = messageService.prepare(
			"Task-Service@" + contextService.getRootContext().getStationIdentifier(),
			IMessageService.INTERNAL_MESSAGE_URI_SCHEME + owner.getId());
		message.addMessageCode(MessageCode.Key.SenderSubId, "tasks.taskservice");
		message.setSenderAcceptsAnswer(false);
		
Loading