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

org.symphonyoss.client.impl.SymphonyBasicClient Maven / Gradle / Ivy

The newest version!
/*
 *
 * Copyright 2016 The Symphony Software Foundation
 *
 * Licensed to The Symphony Software Foundation (SSF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.symphonyoss.client.impl;


import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.symphonyoss.client.SymphonyClient;
import org.symphonyoss.client.SymphonyClientConfig;
import org.symphonyoss.client.SymphonyClientConfigID;
import org.symphonyoss.client.common.Constants;
import org.symphonyoss.client.exceptions.AuthenticationException;
import org.symphonyoss.client.exceptions.InitException;
import org.symphonyoss.client.exceptions.SymCacheException;
import org.symphonyoss.client.exceptions.SymException;
import org.symphonyoss.client.model.CacheType;
import org.symphonyoss.client.model.SymAuth;
import org.symphonyoss.client.services.*;
import org.symphonyoss.symphony.clients.*;
import org.symphonyoss.symphony.clients.jmx.ClientCheck;
import org.symphonyoss.symphony.clients.model.ApiVersion;
import org.symphonyoss.symphony.clients.model.SymUser;
import org.symphonyoss.symphony.pod.invoker.JSON;

import javax.management.*;
import javax.ws.rs.client.Client;
import java.lang.management.ManagementFactory;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Implements a full abstraction of underlying clients and exposes services to simplify
 * functional collaboration elements.  Although all clients are exposed, it's highly recommended
 * to access core functions through services.
 * 

* You must init this class with valid key and session tokens with stored in a SymAuth object. * Please note, that the SymAuth expires and must be updated periodically to maintain access to * the Symphony network. * * @author Frank Tarsillo */ public class SymphonyBasicClient implements SymphonyClient { private final Logger logger = LoggerFactory.getLogger(SymphonyBasicClient.class); private SymAuth symAuth; private MessageService messageService; private ChatService chatService; private RoomService roomService; private PresenceService presenceService; private SymUser localUser; private String agentUrl; private String podUrl; private MessagesClient messagesClient; private DataFeedClient dataFeedClient; private UsersClient usersClient; private StreamsClient streamsClient; private PresenceClient presenceClient; private RoomMembershipClient roomMembershipClient; private AttachmentsClient attachmentsClient; private ConnectionsClient connectionsClient; private ShareClient shareClient; private SymphonyApis symphonyApis; private Client defaultHttpClient; private Client podHttpClient; private Client agentHttpClient; private SymphonyClientConfig config; private final long SYMAUTH_REFRESH_TIME = Long.parseLong(System.getProperty(Constants.SYMAUTH_REFRESH_TIME, "7200000")); private SymUserCache symUserCache; private ApiVersion apiVersion = ApiVersion.V4; private String name; private Timer timer; public SymphonyBasicClient() { this(ApiVersion.V4); } public SymphonyBasicClient(ApiVersion apiVersion) { this.apiVersion = apiVersion; } @Override public void init(SymphonyClientConfig config) throws InitException, AuthenticationException { this.config = config; try { init(CustomHttpClient.getDefaultHttpClient(config), config); } catch (Exception e) { throw new InitException("Failed to initialize network...", e); } } /** * Set name of SJC to be used for threading * * @param name Used for threading */ @Override public void setName(String name) { this.name = name; } /** * Return name of SJC * * @return Name of SJC */ @Override public String getName() { return this.name; } /** * Initialize the SJC with a custom http client for both pod and agent connectivity. * * @param podHttpClient Custom http client to use when connecting to the pod * @param agentHttpClient Custom http client to use when connecting to the agent server * @param config Configuration object * @throws InitException Exception from initialization * @throws AuthenticationException Exception from authorization. */ @Override public void init(Client podHttpClient, Client agentHttpClient, SymphonyClientConfig config) throws InitException, AuthenticationException { this.podHttpClient = podHttpClient; this.agentHttpClient = agentHttpClient; this.defaultHttpClient = podHttpClient; this.config = config; AuthenticationClient authClient = new AuthenticationClient( config.get(SymphonyClientConfigID.SESSIONAUTH_URL), config.get(SymphonyClientConfigID.KEYAUTH_URL), agentHttpClient); SymAuth symAuth = authClient.authenticate(); init(symAuth, config); } @Override public void init(Client httpClient, SymphonyClientConfig config) throws InitException, AuthenticationException { this.defaultHttpClient = httpClient; init(defaultHttpClient, defaultHttpClient, config); } /** * Initialize client with required parameters. * * @param symAuth Contains valid key and session tokens generated from AuthenticationClient. * @param userEmail Email address of the BOT * @param agentUrl The Agent URL * @param podUrl The Service URL (in most cases it's the POD URL) * @throws InitException Failure of a specific service most likely due to connectivity issues */ @Override @Deprecated public void init(SymAuth symAuth, String userEmail, String agentUrl, String podUrl) throws InitException { updateConfig(agentUrl, podUrl, userEmail); init(symAuth, config); } /** * Initialize client with required parameters. Services will be enabled by default. * * @param httpClient Custom http client to use when initiating the client * @param symAuth Contains valid key and session tokens generated from AuthenticationClient. * @param userEmail Email address of the BOT * @param agentUrl The Agent URL * @param podUrl The Service URL (in most cases it's the POD URL) * @throws InitException Failure of a specific service most likely due to connectivity issues */ @Override @Deprecated public void init(Client httpClient, SymAuth symAuth, String userEmail, String agentUrl, String podUrl) throws InitException { this.defaultHttpClient = httpClient; this.agentHttpClient = httpClient; this.defaultHttpClient = httpClient; updateConfig(agentUrl, podUrl, userEmail); init(symAuth, config); } /** * Initialize client with required parameters. * * @param symAuth Contains valid key and session tokens generated from AuthenticationClient. * @param userEmail Email address of the BOT * @param agentUrl The Agent URL * @param podUrl The Service URL (in most cases it's the POD URL) * @param disableServices Disable all real-time services (MessageService, RoomService, ChatService) * @throws InitException Failure of a specific service most likely due to connectivity issues */ @Override @Deprecated public void init(SymAuth symAuth, String userEmail, String agentUrl, String podUrl, boolean disableServices) throws InitException { updateConfig(agentUrl, podUrl, userEmail); config.set(SymphonyClientConfigID.DISABLE_SERVICES, String.valueOf(disableServices)); init(symAuth, config); } /** * Initialize client with required parameters. * * @param symAuth Contains valid key and session tokens generated from AuthenticationClient. * @param config Symphony client config * @throws InitException Failure of a specific service most likely due to connectivity issues */ @Override public void init(SymAuth symAuth, SymphonyClientConfig config) throws InitException { this.config = config; this.symAuth = symAuth; updateConfig(config); try { if (defaultHttpClient == null) defaultHttpClient = CustomHttpClient.getDefaultHttpClient(config); } catch (Exception e) { logger.error("Could not set default http client from config...", e); } if (podHttpClient == null) podHttpClient = defaultHttpClient; if (agentHttpClient == null) agentHttpClient = defaultHttpClient; String NOT_LOGGED_IN_MESSAGE = "Currently not logged into Agent, please check certificates and tokens."; if (symAuth == null || symAuth.getSessionToken() == null || symAuth.getKeyToken() == null) throw new InitException("Symphony Authorization is not valid", new Throwable(NOT_LOGGED_IN_MESSAGE)); if (config.get(SymphonyClientConfigID.AGENT_URL) == null) throw new InitException("Failed to provide agent URL", new Throwable("Failed to provide agent URL")); if (config.get(SymphonyClientConfigID.POD_URL) == null) throw new InitException("Failed to provide service URL", new Throwable("Failed to provide service URL")); this.symAuth = symAuth; this.name = config.get(SymphonyClientConfigID.USER_EMAIL); //Init all clients. dataFeedClient = DataFeedFactory.getClient(this); messagesClient = MessagesFactory.getClient(this); presenceClient = PresenceFactory.getClient(this); streamsClient = StreamsFactory.getClient(this); usersClient = UsersFactory.getClient(this); shareClient = ShareFactory.getClient(this); attachmentsClient = AttachmentsFactory.getClient(this); roomMembershipClient = RoomMembershipFactory.getClient(this); connectionsClient = ConnectionsFactory.getClient(this); symphonyApis = SymphonyApisFactory.getClient(this); try { if (!Boolean.parseBoolean(config.get(SymphonyClientConfigID.DISABLE_SERVICES, "False"))) { messageService = new MessageService(this); chatService = new ChatService(this); roomService = new RoomService(this); presenceService = new PresenceService(this); } localUser = usersClient.getUserBySession(symAuth); } catch (SymException e) { logger.error("Failed to initialize client..", e); throw new InitException("Could not initialize one of the Symphony API services." + " This is most likely due to not having the right agent or pod URLs." + " This can also be an issue with the client certificate or server.truststore." + " Here is what you have configured:\n" + "SessionToken: " + symAuth.getSessionToken() + "\n" + "KeyToken: " + symAuth.getKeyToken() + "\n" + "Email: " + config.get(SymphonyClientConfigID.USER_EMAIL) + "\n" + "AgentUrl: " + config.get(SymphonyClientConfigID.AGENT_URL) + "\n" + "podUrl: " + config.get(SymphonyClientConfigID.POD_URL)); } symUserCache = new DefaultUserCache(this); //Refresh token every so often.. TimerTask authRefreshTask = new AuthRefreshTask(this); // running timer task as daemon thread timer = new Timer("AuthRefresh:" + this.getName(), true); timer.scheduleAtFixedRate(authRefreshTask, SYMAUTH_REFRESH_TIME, SYMAUTH_REFRESH_TIME); //Publish MBean via JMX //Default is true if (Boolean.parseBoolean(config.get(SymphonyClientConfigID.HEALTHCHECK_JMX_ENABLED, "True"))) { logger.info("Registering JMX Health Bean..."); this.registerHealthMBean(); } } @Override public SymAuth getSymAuth() { return symAuth; } /** * @param symAuth Contains valid key and session tokens generated from AuthenticationClient. */ @Override public void setSymAuth(SymAuth symAuth) { this.symAuth = symAuth; } @Override public String getAgentUrl() { return agentUrl; } /** * @param agentUrl Agent URL */ public void setAgentUrl(String agentUrl) { this.agentUrl = agentUrl; } /** * @return Service URL which can be either the Agent URL or POD URL */ @Override public String getPodUrl() { return podUrl; } /** * @param podUrl Service URL which can be either the Agent URL or POD URL */ @SuppressWarnings("unused") public void setPodUrl(String podUrl) { this.podUrl = podUrl; } /** * @return DataFeedClient */ @Override public DataFeedClient getDataFeedClient() { return dataFeedClient; } /** * @return MessagesClient */ @Override public MessagesClient getMessagesClient() { return messagesClient; } /** * @return MessagesService */ @Override public MessageService getMessageService() { return messageService; } @Override public RoomService getRoomService() { return roomService; } @Override public SymUser getLocalUser() { return localUser; } @SuppressWarnings("unused") public void setLocalUser(SymUser localUser) { this.localUser = localUser; } @Override public ChatService getChatService() { return chatService; } @Override public PresenceClient getPresenceClient() { return presenceClient; } @Override public StreamsClient getStreamsClient() { return streamsClient; } @Override public UsersClient getUsersClient() { return usersClient; } @Override public RoomMembershipClient getRoomMembershipClient() { return roomMembershipClient; } @Override public AttachmentsClient getAttachmentsClient() { return attachmentsClient; } @Override public ConnectionsClient getConnectionsClient() { return connectionsClient; } @Override public ShareClient getShareClient() { return shareClient; } /** * Provides the default http client if one is set. * * @return Default http client if set */ @Override public Client getDefaultHttpClient() { return defaultHttpClient; } @Override public void setDefaultHttpClient(Client defaultHttpClient) { this.defaultHttpClient = defaultHttpClient; } @Override public void setCache(SymCache symCache) throws SymCacheException { if (symCache.getCacheType() == null) throw new SymCacheException("Cache type not set..."); if (symCache.getCacheType() == CacheType.USER) symUserCache = (SymUserCache) symCache; } @Override public SymCache getCache(CacheType cacheType) { if (cacheType == CacheType.USER) return symUserCache; return null; } @Override public void shutdown() { if (getMessageService() != null) getMessageService().shutdown(); if (getPresenceService() != null) getPresenceService().shutdown(); if (timer != null) timer.cancel(); } @Override public Client getPodHttpClient() { return podHttpClient; } @Override public void setPodHttpClient(Client podHttpClient) { this.podHttpClient = podHttpClient; } @Override public Client getAgentHttpClient() { return agentHttpClient; } @Override public void setAgentHttpClient(Client agentHttpClient) { this.agentHttpClient = agentHttpClient; } @Override public SymphonyApis getSymphonyApis() { return symphonyApis; } @Override public SymphonyClientConfig getConfig() { return config; } @Override public void setConfig(SymphonyClientConfig config) { this.config = config; } @Override public PresenceService getPresenceService() { return presenceService; } /** * Added to support transition to SymphonyClientConfig init. Will be removed in next major version. * * @param agentUrl Agent URL * @param podUrl Pod URL * @param userEmail Bot user email */ private void updateConfig(String agentUrl, String podUrl, String userEmail) { if (config == null) { config = new SymphonyClientConfig(false); } config.set(SymphonyClientConfigID.AGENT_URL, agentUrl); config.set(SymphonyClientConfigID.POD_URL, podUrl); config.set(SymphonyClientConfigID.USER_EMAIL, userEmail); } /** * Added to support transition to SymphonyClientConfig init. Will be removed in next major version. * * @param config SymphonyClientConfig */ private void updateConfig(SymphonyClientConfig config) { agentUrl = config.get(SymphonyClientConfigID.AGENT_URL); podUrl = config.get(SymphonyClientConfigID.POD_URL); } private void registerHealthMBean() { logger.info("Exposing SymAgentHealthCheck as JMX MBean..."); ClientCheck clientCheck = new ClientCheck(this); MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); String mBeanName = "org.symphonyoss.client:type=ClientCheckMBean"; try { ObjectName mBean = new ObjectName(mBeanName); mbs.registerMBean(clientCheck, mBean); logger.info("Registered JMX Mbean: "+mbs.getMBeanInfo(mBean).getClassName()); } catch (ReflectionException e) { logger.error("Cannot register JMX Mbean: "+mBeanName,e); } catch (InstanceNotFoundException e) { logger.error("Cannot register JMX Mbean: "+mBeanName,e); } catch (IntrospectionException e) { logger.error("Cannot register JMX Mbean: "+mBeanName,e); } catch (MBeanRegistrationException e) { logger.error("Cannot register JMX Mbean: "+mBeanName,e); } catch (MalformedObjectNameException e) { logger.error("Cannot register JMX Mbean: "+mBeanName,e); } catch (InstanceAlreadyExistsException e) { logger.error("Cannot register JMX Mbean: "+mBeanName,e); } catch (NotCompliantMBeanException e) { logger.error("Cannot register JMX Mbean: "+mBeanName,e); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy