Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* ************************************************************************
  #
  #  DivConq
  #
  #  http://divconq.com/
  #
  #  Copyright:
  #    Copyright 2014 eTimeline, LLC. All rights reserved.
  #
 #  License:
 #    See the license.txt file in the project's top-level directory for details.
 #
 #  Authors:
 #    * Andy White
 #
 ************************************************************************ */
 package divconq.lang;
 
 
 
Almost all code that executes after Hub.start should have a context. The context tells the code who the user responsible for the task is, what their access levels are (at a high level), what language/locale/chronology(timezone) they use, how to log the debug messages for the task, and whether or not the user has been authenticated or not. Although the task context is associated with the current thread, it is the task that the context belongs to, not the thread. If a task splits into multiple threads there is still one TaskContext, even if the task makes a remote call on DivConq's bus that remote call executes on the TaskContext. As long as you use the built-in features - work pool, scheduler, bus, database - the task context will smoothly come along with no effort from the app developer. A quick guide to what context to use where: Hub Context - useHubContext() The code is running as part of the Hub core. Root Context - useNewRoot() Root context is the same identity as Hub, but with useNewRoot() you get a new log id. Use this with code running batch tasks that belong to the system rather than a specific user. Guest Context - useNewGuest() Guest context is for use by an anonymous user. For example a user through the interchange (HTTP, FTP, SFTP, EDI, etc). User Context - new TaskContext + set(tc) When a user signs-in create and set a new context. No need to authenticate against the database that will happen automatically (as long as you follow DivConq development guidelines) so think of creating the user Task Context as information gathering not authentication.

Author(s):
Andy
 
 public class OperationContext {
 	static protected String runid = null;
 	static protected String hubid = "00001";
 	static protected OperationContext hubcontext = null;
 	
 	static protected AtomicLong nextid = new AtomicLong();
 	
 	static {
 		. = OperationContext.useNewRoot();
 	}
 	
 	static public String getHubId() {
 	}
 	
 	static public void setHubId(String v) {
 		if (StringUtil.isEmpty(v))
 			return;
 		
 		// only set once
 			return;
 		
		. = OperationContext.useNewRoot();		// reset the hub context 
	}
	static public String getRunId() {
	}

Returns:
the hub context, use by code running in the "core" code of Hub (e.g. main thread)
	static public OperationContext getHubContext() {
	}

Sets the current thread to use the hub context

Returns:
the hub context, use by code running in the "core" code of Hub (e.g. main thread)
	static public OperationContext useHubContext() {
	}
	public static void startHubContext(XElement config) {
		// TODO load up info from config - this is the only time TC or UC
		// should be mutated, only internally and only the special root
		// instances
		OperationContext.updateHubContext();
	}
	public static void updateHubContext() {
		// this is the only time TC or UC should be mutated, only internally
		//  and only the special root instances
	}

Returns:
context of the current thread, if any otherwise the guest context
	static public OperationContext get() {
		if (tc != null)
			return tc;
		return OperationContext.allocateGuest();
	}
	// does the current thread have a context?
	static public boolean hasContext() {
		return (..get() != null);
	}

Parameters:
v context for current thread to use
	static public void set(OperationContext v) {
	}

Returns:
context of the current thread, if any, otherwise the hub context
	static public OperationContext getOrHub() {
		if (tc == null)
		return tc;
	}

Returns:
create a new guest context
	static public OperationContext allocateGuest() {
	}

Sets the current thread to use a new guest context

Returns:
create a new guest context
	static public OperationContext useNewGuest() {
		OperationContext tc = OperationContext.allocateGuest();
		return tc;
	}

Returns:
create a new root context
	static public OperationContext allocateRoot() {
	}

Sets the current thread to use a new root context

Returns:
create a new root context
	static public OperationContext useNewRoot() {
		OperationContext tc = OperationContext.allocateRoot();
		return tc;
	}
	/*
	 * Sets the current thread to use a new context
	 * 
	 * @return create a new context
	 */
		OperationContext tc = OperationContext.allocate(tcb);
		return tc;
	}
		OperationContext tc = OperationContext.allocate(ctxtcb);
		return tc;
	}
	/*
	 * @param m create a task context from a message (RPC calls to dcBus), keep in mind
	 * this is info gathering only, message must not be allowed to force an 
	 * authenticated/elevated state inappropriately - from RPC clear "Elevated"
	 * field before calling this
	 */
	static public OperationContext allocate(Message m) {
		return new OperationContext(m.getFieldAsRecord("Context")); 
	}
	static public OperationContext allocate(RecordStruct ctx) {
		return new OperationContext(ctx); 
	}
	static public OperationContext allocate(UserContext usrRecordStruct ctx) {
		return new OperationContext(usrctx); 
	}
		return new OperationContext(tcb.values); 
	}
		return new OperationContext(usrtcb.values); 
	}	
	protected static String allocateOpId() {
		// TODO confirm this really does work
		/*
		if (num > 999999999999999L) {
			synchronized (TaskContext.nextid) {
				if (TaskContext.nextid.get()> 999999999999999L)
					TaskContext.nextid.set(0);				
			}
			num = TaskContext.nextid.getAndIncrement();
		}
		*/
		return OperationContext.getHubId() 
"_" + OperationContext.getRunId() 
"_" + StringUtil.leftPad(num + "", 15, '0');
	}
	/*
	 * set current thread context to null 
	 */
	static public void clear() {
	}
	static public void isGuest(final FuncCallback<Booleancb) {
		OperationContext.isGuest(OperationContext.get(), cb);
	}
	/*
	 * @return check to see if the task is really no more than a guest access.  does not change task context
	 */
	static public void isGuest(OperationContext ctxfinal FuncCallback<Booleancb) {
		if ((ctx == null) || (ctx.userctx == null)) {
			cb.setResult(false);
			return;
		}
		if (ctx.userctx.looksLikeGuest()) {
			cb.setResult(true);
			return;
		}
			public void callback() {
				// be sure to call TaskContext.get() because task context can change during verify
			}
		});
	}
	// instance code
	protected RecordStruct opcontext = null;
	protected UserContext userctx = null;
	protected DebugLevel level = Logger.getGlobalLevel();
	// once elevated we can call any service we want, but first we must
	// call a service we are allowed to call
	/*
	 * Elevated tasks have been a) authenticated and b) passed successfully into
	 * a service.  Once elevated all subsequent calls with the task no longer need
	 * to be authenticated or authorized by DivConq framework (individual services/modules
	 * may require it).  Meaning that "guest" cannot call "SendMail" unless it first 
	 * goes through a service that is open to guests, such as password recovery.  
	 * 
	 * Mark the task context as elevated - typically app code does not need to call
	 * this because the services and scheduler handlers decide when a task has met
	 * the desired state. 
	 */

Returns:
a unique task id - unique across all deployed hub, across runs of a hub
	public String getOpId() {
		return this..getFieldAsString("OpId");
	}

Returns:
the the user context for this task (user context may be shared with other tasks)
		return this.;
	}

not all tasks will have a session, but if there is a session here it is. id is in the format of hubid_sessionid

Returns:
the id of the session that spawned this task
	public String getSessionId() {
		return this..getFieldAsString("SessionId");
	}

not all tasks will have a session, but if there is a session here it is. sessions are local to a hub and are not transfered to another hub with the rest of the task info when calling a remote service.

Returns:
the session for this task (user context may be shared with other tasks)
	public Session getSession() {
	}

Returns:
logging level to use with this task
	public DebugLevel getLevel() {
		return this.;
	}

Origin indicates where this task originated from. "hub:" means it was started by the a hub (task id gives away which hub). "http:[ip address]" means the task was started in response to a web request. "ws:[ip address]" means the task was started in response to a web scoket request. "ftp:[ip address]" means the task was started in response to a ftp request. Etc.

Returns:
origin string
	public String getOrigin() {
		return this..getFieldAsString("Origin");
	}

Elevated tasks have been a) authenticated and b) passed successfully into a service. Once elevated all subsequent calls with the task no longer need to be authenticated or authorized by DivConq framework (individual services/modules may require it). Meaning that "guest" cannot call "SendMail" unless it first goes through a service that is open to guests, such as password recovery.

Returns:
true if task has been elevated
	public boolean isElevated() {
		return this..getFieldAsBooleanOrFalse("Elevated");
	}

Parameters:
ctx create a task context from a RecordStruct, keep in mind this is info gathering only, call must set authenticated/elevated state inappropriately
	protected OperationContext(RecordStruct ctx) {
		this. = ctx;
		if (ctx.isFieldEmpty("OpId"))
			ctx.setField("OpId", OperationContext.allocateOpId());		
		if (!ctx.isFieldEmpty("DebugLevel"))
			this. = DebugLevel.valueOf(ctx.getFieldAsString("DebugLevel"));	
		this. = UserContext.allocateFromTask(ctx);
	}
	protected OperationContext(UserContext usrRecordStruct ctx) {
		this. = ctx;
		if (ctx.isFieldEmpty("OpId"))
			ctx.setField("OpId", OperationContext.allocateOpId());		
		if (!ctx.isFieldEmpty("DebugLevel"))
			this. = DebugLevel.valueOf(ctx.getFieldAsString("DebugLevel"));	
		this. = usr;
	}
	}

Parameters:
m store task context into a message - for context transfer over bus
	public void freeze(Message m) {
		m.setField("Context"this.freezeToRecord());
	}
		this..freeze(clone);
		clone.setField("DebugLevel"this..toString());
		return clone;
	}
		this..freezeSafe(clone);
		clone.setField("DebugLevel"this..toString());
		return clone;
	}
	// return an approved/verified user context (guest if nothing else)
	// verify says - the given auth token, if any, is valid - if there is none then you are a guest and that is valid
	// 
	public void verify(FuncCallback<UserContextcb) {
		if (this. == null) {
			cb.errorTr(444);
			cb.setResult(UserContext.allocateGuest());
			return;
		}
		if (this..isVerified() || this.isElevated()) {
			return;
		}
		Message msg = new Message("dcAuth""Authentication""Verify");
    	
		..getBus().sendMessage(msgr ->	{		
			if (r.hasErrors()) 
				cb.setResult(UserContext.allocateGuest());
			else 
		});
	}

Parameters:
tags to search for with this user
Returns:
true if this user has one of the requested authorization tags (does not check authentication)
	public boolean isAuthorized(String... tags) {
		if (this.isElevated())
			return true;		// always ok
		if (!this..isVerified())
			return false;
		return this..isTagged(tags);
	}
	public String toString() {
		// capture both this and the user
		return this.freezeToRecord().toPrettyString(); 
	}
    
    public void error(String messageString... tags) {
    	Logger.log(this.messagetags);
    }
    
    public void warn(String messageString... tags) {
    	Logger.log(this.messagetags);
    }
    
    public void info(String messageString... tags) {
    	Logger.log(this.messagetags);
    }
    
    public void trace(String messageString... tags) {
    	Logger.log(this.messagetags);
    }
    
    public void debug(String messageString... tags) {
    	Logger.log(this.messagetags);
    }
    
    public void logBoundary(String... tags) {
    	Logger.boundary(thistags);
    }
    
    public void log(DebugLevel levelString messageString... tags) {
    	Logger.log(thislevelmessagetags);
    }
    // let Logger translate to the language of the log file - let tasks translate to their own logs in
    // the language of the TaskContext - so below does not accomplish the goals
    

Parameters:
code for message translation token
params for message translation
	public void traceTr(long codeObject... params) {
    	Logger.log(this.codeparams);
	}

Parameters:
code for message translation token
params for message translation
	public void debugTr(long codeObject... params) {
    	Logger.log(this.codeparams);
	}

Parameters:
code for message translation token
params for message translation
	public void infoTr(long codeObject... params) {		
    	Logger.log(this.codeparams);
	}

Parameters:
code for message translation token
params for message translation
	public void warnTr(long codeObject... params) {
    	Logger.log(this.codeparams);
	}

Parameters:
code for message translation token
params for message translation
	public void errorTr(long codeObject... params) {
    	Logger.log(this.codeparams);
	}
	public String tr(String tokenObject... params) {
		return this..tr(tokenparams);
	}
	public String trp(String pluraltokenString singulartokenObject... params) {
		return this..trp(pluraltokensingulartokenparams);
	}
New to GrepCode? Check out our FAQ X