I am developing a unity project which requires a MySQL connection.
My connection works fine in Unity and Android builds, but when I build the whole project into iOS platform, I had an error (I have localized this through a reporter plugin)
First an exception:
System.ArgumentException: Keyword not supported. Parameter name: pwd at MySql.Data.MSqlClient.MySqlConnectionStringBuilder.ValidateKeyword (System.String keyword) [0x000000] in <filename unknown>:0
Later an error:
NullReferenceException: A null value was found where an object instance was required.
HandlerMySQL.Conectar ()
The code is the following
using System.Collections.Generic;
using System.Security.Cryptography;
using MySql.Data;
using MySql.Data.MySqlClient;
public class HandlerMySQL{
public string host, database, user, password;
public bool pooling = true;
private string connectionString;
private static MySqlConnection con = null;
private MySqlCommand cmd = null;
private MySqlDataReader rdr = null;
private MD5 _md5Hash;
public HandlerMySQL(string h,string db, string u, string pw)
{
host = h;
database = db;
user = u;
password = pw;
}
public void Conectar()
{
connectionString = "Server=" + host + ";Database=" + database + ";Uid=" + user + ";Pwd=" + password + ";Pooling=";
if (pooling)
{
connectionString += "true;";
}
else
{
connectionString += "false;";
}
try
{
con = new MySqlConnection(connectionString);
con.Open();
Debug.Log("MySQL State: " + con.State);
}
catch(Exception e)
{
Debug.Log(e);
Debug.Log("MySQL State: " + con.State);
}
}
void OnApplicationQuit()
{
if (con != null)
{
if (con.State.ToString() != "Close")
{
con.Close();
Debug.Log("MySQL Connection closed");
}
con.Dispose();
}
}
public bool GetIsConnected()
{
if (con.State.ToString() == "Open")
{
return true;
}
else
{
return false;
}
}
public bool CreateData(string dnow, string dstart,int dend)
{
DataMySql data = new DataMySql(dnow, dstart, dend);
if (DataToolsMySql.Agregar(data, con) > 0)
{
Debug.Log("Se agrego correctamente");
return true;
}
else
{
Debug.Log("ERROR!!! No se agrego");
return false;
}
}
}
Related
I exposed Rest APIs, and I generated client code using Swagger 2 Java language with Feign library. The code gen generated the below OAuth RequestInterceptor. I am getting the below error when I use the oAuth as auth.
Error
feign.RetryableException: url values must be not be absolute.
at com.sam.feign.auth.OAuth.updateAccessToken(OAuth.java:95)
at com.sam.feign.auth.OAuth.apply(OAuth.java:83)
at feign.SynchronousMethodHandler.targetRequest(SynchronousMethodHandler.java:161)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:110)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:89)
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100)
at com.sun.proxy.$Proxy9.getUser(Unknown Source)
at com.sam.feign.clients.UserApiTest.getUserTest(UserApiTest.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by: java.lang.IllegalArgumentException: url values must be not be absolute.
at feign.RequestTemplate.uri(RequestTemplate.java:434)
at feign.RequestTemplate.uri(RequestTemplate.java:421)
at feign.RequestTemplate.append(RequestTemplate.java:388)
at com.sam.feign.auth.OAuth$OAuthFeignClient.execute(OAuth.java:163)
at org.apache.oltu.oauth2.client.OAuthClient.accessToken(OAuthClient.java:65)
at org.apache.oltu.oauth2.client.OAuthClient.accessToken(OAuthClient.java:55)
at org.apache.oltu.oauth2.client.OAuthClient.accessToken(OAuthClient.java:71)
at com.sam.feign.auth.OAuth.updateAccessToken(OAuth.java:93)
... 34 more
Swagger Generated oAuth supporting file
public class OAuth implements RequestInterceptor {
static final int MILLIS_PER_SECOND = 1000;
public interface AccessTokenListener {
void notify(BasicOAuthToken token);
}
private volatile String accessToken;
private Long expirationTimeMillis;
private OAuthClient oauthClient;
private TokenRequestBuilder tokenRequestBuilder;
private AuthenticationRequestBuilder authenticationRequestBuilder;
private AccessTokenListener accessTokenListener;
public OAuth(Client client, TokenRequestBuilder requestBuilder) {
this.oauthClient = new OAuthClient(new OAuthFeignClient(client));
this.tokenRequestBuilder = requestBuilder;
}
public OAuth(Client client, OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
this(client, OAuthClientRequest.tokenLocation(tokenUrl).setScope(scopes));
switch(flow) {
case accessCode:
case implicit:
tokenRequestBuilder.setGrantType(GrantType.AUTHORIZATION_CODE);
break;
case password:
tokenRequestBuilder.setGrantType(GrantType.PASSWORD);
break;
case application:
tokenRequestBuilder.setGrantType(GrantType.CLIENT_CREDENTIALS);
break;
default:
break;
}
authenticationRequestBuilder = OAuthClientRequest.authorizationLocation(authorizationUrl);
}
public OAuth(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
this(new Client.Default(null, null), flow, authorizationUrl, tokenUrl, scopes);
}
#Override
public void apply(RequestTemplate template) {
// If the request already have an authorization (eg. Basic auth), do nothing
if (template.headers().containsKey("Authorization")) {
return;
}
// If first time, get the token
if (expirationTimeMillis == null || System.currentTimeMillis() >= expirationTimeMillis) {
updateAccessToken(template);
}
if (getAccessToken() != null) {
template.header("Authorization", "Bearer " + getAccessToken());
}
}
public synchronized void updateAccessToken(RequestTemplate template) {
OAuthJSONAccessTokenResponse accessTokenResponse;
try {
accessTokenResponse = oauthClient.accessToken(tokenRequestBuilder.buildBodyMessage());
} catch (Exception e) {
throw new RetryableException(400, e.getMessage(), template.request().httpMethod(), e, null, template.request());
}
if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) {
setAccessToken(accessTokenResponse.getAccessToken(), accessTokenResponse.getExpiresIn());
if (accessTokenListener != null) {
accessTokenListener.notify((BasicOAuthToken) accessTokenResponse.getOAuthToken());
}
}
}
public synchronized void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
this.accessTokenListener = accessTokenListener;
}
public synchronized String getAccessToken() {
return accessToken;
}
public synchronized void setAccessToken(String accessToken, Long expiresIn) {
this.accessToken = accessToken;
this.expirationTimeMillis = System.currentTimeMillis() + expiresIn * MILLIS_PER_SECOND;
}
public TokenRequestBuilder getTokenRequestBuilder() {
return tokenRequestBuilder;
}
public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) {
this.tokenRequestBuilder = tokenRequestBuilder;
}
public AuthenticationRequestBuilder getAuthenticationRequestBuilder() {
return authenticationRequestBuilder;
}
public void setAuthenticationRequestBuilder(AuthenticationRequestBuilder authenticationRequestBuilder) {
this.authenticationRequestBuilder = authenticationRequestBuilder;
}
public OAuthClient getOauthClient() {
return oauthClient;
}
public void setOauthClient(OAuthClient oauthClient) {
this.oauthClient = oauthClient;
}
public void setOauthClient(Client client) {
this.oauthClient = new OAuthClient( new OAuthFeignClient(client));
}
public static class OAuthFeignClient implements HttpClient {
private Client client;
public OAuthFeignClient() {
this.client = new Client.Default(null, null);
}
public OAuthFeignClient(Client client) {
this.client = client;
}
public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,
String requestMethod, Class<T> responseClass)
throws OAuthSystemException, OAuthProblemException {
RequestTemplate req = new RequestTemplate()
.append(request.getLocationUri())
.method(requestMethod)
.body(request.getBody());
for (Entry<String, String> entry : headers.entrySet()) {
req.header(entry.getKey(), entry.getValue());
}
Response feignResponse;
String body = "";
try {
feignResponse = client.execute(req.request(), new Options());
body = Util.toString(feignResponse.body().asReader());
} catch (IOException e) {
throw new OAuthSystemException(e);
}
String contentType = null;
Collection<String> contentTypeHeader = feignResponse.headers().get("Content-Type");
if(contentTypeHeader != null) {
contentType = StringUtil.join(contentTypeHeader.toArray(new String[0]), ";");
}
return OAuthClientResponseFactory.createCustomResponse(
body,
contentType,
feignResponse.status(),
responseClass
);
}
public void shutdown() {
// Nothing to do here
}
}
}
ApiClient.java have the below absolute URL which configured in swagger spec
public ApiClient() {
objectMapper = createObjectMapper();
apiAuthorizations = new LinkedHashMap<String, RequestInterceptor>();
feignBuilder = Feign.builder()
.encoder(new FormEncoder(new JacksonEncoder(objectMapper)))
.decoder(new JacksonDecoder(objectMapper))
.logger(new Slf4jLogger());
}
public ApiClient(String[] authNames) {
this();
for(String authName : authNames) {
RequestInterceptor auth = null;
if ("client-credentils-oauth2".equals(authName)) {
auth = new OAuth(OAuthFlow.application, "", "http://localhost:8080/app/oauth/token", "user.create");
} else if ("password-oauth2".equals(authName)) {
auth = new OAuth(OAuthFlow.password, "", "http://localhost:8080/app/oauth/token", "openid");
} else {
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
}
addAuthorization(authName, auth);
}
}
Used the below dependencies
swagger-codegen-maven-plugin v2.4.28
feign-version 11.6
feign-form-version 3.8.0
oltu-version 1.0.1
Java 8
I am invoking the client by using below code
UserApi api = new ApiClient("client-credentils-oauth2","admin", "admin", null, null).buildClient(UserApi.class);
api.getUser(login, tenant)
I made the few changes in the generated oAuth.java file to make it work. Expecting the client generated code should work without making any manual changes.
public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,
String requestMethod, Class<T> responseClass)
throws OAuthSystemException, OAuthProblemException {
// Added the below 3 lines
URI targetUri = URI.create(uri);
String target = targetUri.getScheme() + "://" + targetUri.getAuthority() ;
String path = targetUri.getPath();
RequestTemplate req = new RequestTemplate()
.uri(path)
.method(requestMethod)
.body(request.getBody())
.target(target); // Added this line
for (Entry<String, String> entry : headers.entrySet()) {
req.header(entry.getKey(), entry.getValue());
}
req = req.resolve(new HashMap<String, Object>()); // Added this line
Response feignResponse;
String body = "";
try {
feignResponse = client.execute(req.request(), new Options());
body = Util.toString(feignResponse.body().asReader());
} catch (IOException e) {
throw new OAuthSystemException(e);
}
String contentType = null;
Collection<String> contentTypeHeader = feignResponse.headers().get("Content-Type");
if(contentTypeHeader != null) {
contentType = StringUtil.join(contentTypeHeader.toArray(new String[0]), ";");
}
return OAuthClientResponseFactory.createCustomResponse(
body,
contentType,
feignResponse.status(),
responseClass
);
}
Appreciate if someone can assist me with this issue
I have created a Serilog sink that talks to a web service which persists log messages to a database. It works most of the time. Even in cases where there is an exception calling the web service it will log to the Selflog file. However, However, periodically it simply stops logging either to our custom web service or to the self log file and after it stops logging it never begins logging anywhere else. This is being executed in a windows service and I have to stop and restart the windows service before it begins logging again. A typical exception that i might get from the web service call is: "Task was cancelled". This would be caused because the webservice does not respond within the configured timeout period. As I said normally it will properly write the events to the selflog file. Only periodically will it just stop logging everywhere. I should also say that the volume of logs being generated is very high.
This is a dnx project and here is a portion of the project.json file:
"dependencies": {
"Newtonsoft.Json": "8.0.2",
"Serilog.Sinks.PeriodicBatching": "2.0.0",
"Serilog": "2.0.0-beta-465",
"Serilog.Extensions.Logging": "1.0.0-rc1-final-10092",
"JA.AppCentral.Logging.Contracts": "0.1.0-alpha1-*",
"FluentAssertions": "4.2.2",
"Microsoft.Extensions.Configuration": "1.0.0-rc1-final",
"Microsoft.AspNet.WebApi.Client": "4.0.30506"
}
I have included relevant portions of the sink class. It inherits from periodic batching sink.
The code used to configure the Selflog follows:
FileStream fs = new FileStream(selfLogFilePath, fileMode, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
Serilog.Debugging.SelfLog.Out = TextWriter.Synchronized(sw);
Here is the sink code:enter code here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Serilog;
using System.Net.Http;
using Serilog.Core;
using Serilog.Events;
using System.Net.Http.Headers;
using System.IO;
using Serilog.Formatting.Json;
using Serilog.Debugging;
using Newtonsoft.Json;
using JA.AppCentral.Logging.Contracts;
using Microsoft.Extensions.Configuration;
using Serilog.Sinks.PeriodicBatching;
using System.Diagnostics;
using System.Threading;
namespace JA.AppCentral.Logging
{
public class AppCentralSink: Serilog.Sinks.PeriodicBatching.PeriodicBatchingSink
{
readonly HttpClient _httpClient;
LoggingLevelSwitch _levelControlSwitch;
const string BulkAddUri = "api/appLogging/bulkAdd";
private Uri _baseUri;
private string _baseUriPath;
readonly long? _eventBodyLimitBytes = 1000000;
static readonly TimeSpan RequiredLevelCheckInterval = TimeSpan.FromSeconds(10);
private TimeSpan _timeout = TimeSpan.FromMinutes(1);
private bool _saveMessageTemplate;
private int eventsCount;
private LoggingRepositoryServiceResponse _logServiceResponse;
private int _totalInsertedRecords;
public event EventHandler<ResponseEventArgs> ResponseReceived = delegate { };
DateTime _nextRequiredLevelCheckUtc = DateTime.Now.Add(RequiredLevelCheckInterval);
private int osId;
private string server;
private string username;
private int threadId;
private string appcode;
/// <summary>
/// Overloaded constructor, to pass AppSettings via IConfiguration , instead of separate parameters
/// </summary>
/// <param name="config"></param>
public AppCentralSink(IConfiguration config)
: base(Convert.ToInt32(GetConfigParams(config)["BatchSizeLimit"]),
TimeSpan.FromSeconds(Convert.ToDouble(GetConfigParams(config)["BatchEmitIntervalSeconds"])))
{
Dictionary<string, string> appSettingDict = GetConfigParams(config);
long tempLongVal;
long? eventBodyLimitBytes = long.TryParse(appSettingDict["EventBodyMaxSizeBytes"], out tempLongVal) ? tempLongVal : (long?)null;
if (eventBodyLimitBytes != null)
_eventBodyLimitBytes = eventBodyLimitBytes;
bool saveMessageTemplate = Convert.ToBoolean(appSettingDict["LogMessageTemplate"]);
if (saveMessageTemplate != false)
_saveMessageTemplate = saveMessageTemplate;
string serverUrl = appSettingDict["Url"];
//baseUri = "http://localhost:49774/";
if (!serverUrl.EndsWith("/"))
serverUrl += "/";
_baseUriPath = serverUrl;
_baseUri = new Uri(serverUrl);
TimeSpan timeout = TimeSpan.FromSeconds(Convert.ToDouble(appSettingDict["WebRequestTimeoutSeconds"]));
if (timeout != default(TimeSpan))
_timeout = timeout;
//Default Authentication via http client handler
HttpClientHandler handler = new HttpClientHandler()
{
PreAuthenticate = true,
UseDefaultCredentials = true
};
_httpClient = new HttpClient(handler);
_httpClient.BaseAddress = _baseUri;
_httpClient.DefaultRequestHeaders.Accept.Clear();
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
_httpClient.Timeout = _timeout;
//Init Context properties
OsId = Process.GetCurrentProcess().Id;
Server = Environment.MachineName;
Username = Environment.UserName;
ThreadId = Thread.CurrentThread.ManagedThreadId;
Appcode = config["JA:AppCatalog:AppCode"];
}
private static Dictionary<string,string> GetConfigParams(IConfiguration config)
{
Dictionary<string, string> appSettings = new Dictionary<string, string>();
var SerilogSection = config.GetSection("AppCentralLogging");
appSettings.Add("Url", SerilogSection["Url"]);
appSettings.Add("BatchSizeLimit", SerilogSection["BatchSizeLimit"]);
appSettings.Add("BatchEmitIntervalSeconds", SerilogSection["BatchEmitIntervalSeconds"]);
appSettings.Add("EventBodyMaxSizeBytes", SerilogSection["EventBodyMaxSizeBytes"]);
appSettings.Add("LogMessageTemplate", SerilogSection["LogMessageTemplate"]);
appSettings.Add("WebRequestTimeoutSeconds", SerilogSection["WebRequestTimeoutSeconds"]);
appSettings.Add("SelfLogFileLocationAndPrefix", config["Serilog:SelfLogFileLocationAndPrefix"]);
return appSettings;
}
// The sink must emit at least one event on startup, and the server be
// configured to set a specific level, before background level checks will be performed.
protected override void OnEmptyBatch()
{
if (_levelControlSwitch != null &&
_nextRequiredLevelCheckUtc < DateTime.Now)
{
EmitBatch(Enumerable.Empty<LogEvent>());
}
}
protected override async Task EmitBatchAsync(IEnumerable<LogEvent> events)
{
_nextRequiredLevelCheckUtc = DateTime.Now.Add(RequiredLevelCheckInterval);
var formatter = new JsonFormatter();
List<LogEntry> logEntriesList = new List<LogEntry>();
try
{
foreach (var logEvent in events)
{
EventsCount++;
LogEntry jaLogEvent = ConvertToLogEntry(logEvent);
if (_eventBodyLimitBytes.HasValue)
{
var scratch = new StringWriter();
formatter.Format(logEvent, scratch);
var buffered = scratch.ToString();
if (Encoding.UTF8.GetByteCount(buffered) > _eventBodyLimitBytes.Value)
{
SelfLog.WriteLine("Event JSON representation exceeds the byte size limit of {0} set for this sink and will be dropped; data: {1}", _eventBodyLimitBytes, buffered);
}
else
{
logEntriesList.Add(jaLogEvent);
}
}
else
{
logEntriesList.Add(jaLogEvent);
}
}
var result = await _httpClient.PostAsJsonAsync(BulkAddUri, logEntriesList);
if (!result.IsSuccessStatusCode)
{
try
{
var error = await result.Content.ReadAsStringAsync();
var responseExcep = new Exception(error);
throw responseExcep;
}
catch (Exception e)
{
SelfLog.WriteLine("FailedEvents: " + GetEventsAsString(events));
throw new Exception("Error calling Logging Web Service: status code: " + result.StatusCode +
" reason: " + result.ReasonPhrase + " excep: " + e.ToString());
}
}
_logServiceResponse = await result.Content.ReadAsAsync<LoggingRepositoryServiceResponse>();
if (_logServiceResponse.ResponseException != null)
{
SelfLog.WriteLine("FailedEvents: " + GetEventsAsString(events));
SelfLog.WriteLine(_logServiceResponse.ResponseMessage);
throw new Exception("Error calling Logging Web Service: " +
_logServiceResponse.ResponseMessage);
}
_totalInsertedRecords = _totalInsertedRecords + _logServiceResponse.NumRecordsInserted;
ResponseReceived(this, new ResponseEventArgs(result));
}
catch (Exception e)
{
SelfLog.WriteLine("Error processing log batch, excep: " + e.ToString());
SelfLogEvents(events);
throw;
}
}
private void SelfLogEvents(IEnumerable<LogEvent> events)
{
SelfLog.WriteLine("Failed to write following log events:");
foreach (var e in events)
{
SelfLog.WriteLine($" Event: " + e.RenderMessage());
}
}
private string GetEventsAsString(IEnumerable<LogEvent> events)
{
string eventsResult = string.Empty;
foreach(LogEvent le in events)
{
eventsResult += "[" + le.RenderMessage() + "]";
}
return eventsResult;
}
private LogEntry ConvertToLogEntry(LogEvent logEvent)
{
string propertiesString = JsonConvert.SerializeObject(logEvent.Properties);
string messageTemplate = _saveMessageTemplate == true ? logEvent.MessageTemplate.Text : string.Empty;
//Append Exception to the message if it's not null
string logEventMessage = logEvent.RenderMessage();
if (logEvent.Exception != null)
{
logEventMessage = logEventMessage + " Exception: " + logEvent.Exception.ToString();
}
LogEntry logEntry = new LogEntry("AppCode", "Action", logEvent.Level.ToString(), messageTemplate,
logEventMessage, propertiesString,
logEvent.Timestamp);
//Append additional properties
if (String.IsNullOrEmpty(Appcode))
{
logEntry.AppCode = logEvent.Properties.Keys.Contains("appcode") ? logEvent.Properties["appcode"].ToString().Replace("\"", "") : string.Empty;
logEntry.OsPId = logEvent.Properties.Keys.Contains("os_pid") ? logEvent.Properties["os_pid"].ToString().Replace("\"", "") : string.Empty;
logEntry.ThreadId = logEvent.Properties.Keys.Contains("thread_id") ? logEvent.Properties["thread_id"].ToString().Replace("\"", "") : string.Empty;
logEntry.Server = logEvent.Properties.Keys.Contains("server") ? logEvent.Properties["server"].ToString().Replace("\"", "") : string.Empty;
logEntry.Username = logEvent.Properties.Keys.Contains("username") ? logEvent.Properties["username"].ToString().Replace("\"", "") : string.Empty;
}
else
{
logEntry.AppCode = Appcode;
logEntry.OsPId = OsId.ToString();
logEntry.ThreadId = ThreadId.ToString();
logEntry.Server = Server;
logEntry.Username = Username;
}
logEntry.SessionId = logEvent.Properties.Keys.Contains("session_id") ? logEvent.Properties["session_id"].ToString().Replace("\"", "") : string.Empty;
logEntry.Action = logEvent.Properties.Keys.Contains("action") ? logEvent.Properties["action"].ToString().Replace("\"", "") : string.Empty;
//Append SourceContext
//Append SourceContext
LogEventPropertyValue propertyValue;
if (logEvent.Properties.TryGetValue("SourceContext", out propertyValue))
{
logEntry.SourceContext = propertyValue.ToString().Trim(new[] { '"' });
}
return logEntry;
}
public int EventsCount
{
get
{
return eventsCount;
}
set
{
eventsCount = value;
}
}
public LoggingRepositoryServiceResponse LogServiceResponse
{
get
{
return _logServiceResponse;
}
set
{
_logServiceResponse = value;
}
}
public int TotalInsertedRecords
{
get
{
return _totalInsertedRecords;
}
set
{
_totalInsertedRecords = value;
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
_httpClient.Dispose();
}
public HttpClient HttpClient
{
get { return _httpClient; }
}
}
public class ResponseEventArgs : EventArgs
{
public ResponseEventArgs(HttpResponseMessage response)
{
Response = response;
}
public HttpResponseMessage Response { get; }
}
}
I would like to know can I create a new linked task when I create a workitem.
Can anyone give a tip of how to do this?
I've gone through some old code that I previously used for this scenario. The following code creates a linked task whenever a new bug is set to approved.
The code filters to a specific Team Project and uses a specific account to connect. You need to enter these before the plugin will work. You can then modify this code to create the tasks you want.
For a general introduction to server plugins and how to turn the code below into a functioning plugin see Extending Team Foundation
using Microsoft.TeamFoundation.Framework.Server;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.Common;
using Microsoft.TeamFoundation.WorkItemTracking.Server;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.Client;
using System.Net;
using System.Collections;
namespace TfsExtension.CreateTaskForBug
{
public class CreateTaskForBugEventHandler : ISubscriber
{
const string projectName = "<Enter your project name here>";
public string Name
{
get
{
return "CreateTaskForBugEventHandler";
}
}
public SubscriberPriority Priority
{
get
{
return SubscriberPriority.Normal;
}
}
public EventNotificationStatus ProcessEvent(
TeamFoundationRequestContext requestContext,
NotificationType notificationType,
object notificationEventArgs,
out int statusCode,
out string statusMessage,
out ExceptionPropertyCollection properties)
{
statusCode = 0;
properties = null;
statusMessage = String.Empty;
try
{
ProcessNotification(notificationType, notificationEventArgs, requestContext);
}
catch (Exception exception)
{
TeamFoundationApplicationCore.LogException("Error processing event", exception);
}
return EventNotificationStatus.ActionPermitted;
}
private static void ProcessNotification(NotificationType notificationType, object notificationEventArgs, TeamFoundationRequestContext requestContext)
{
if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
{
var ev = notificationEventArgs as WorkItemChangedEvent;
if (ev.PortfolioProject == projectName)
{
string workItemType = (from field in ev.CoreFields.StringFields
where field.Name == "Work Item Type"
select field.NewValue).Single();
if (workItemType == "Bug")
{
ProcessBug(ev, requestContext);
}
}
}
}
private static void ProcessBug(WorkItemChangedEvent ev, TeamFoundationRequestContext requestContext)
{
var stateChange = (from field in ev.ChangedFields.StringFields
where field.Name == "State" && field.NewValue == "Approved"
select field).SingleOrDefault();
if (stateChange != null)
{
AddChildTaskToBug(ev, requestContext);
}
}
private static void AddChildTaskToBug(WorkItemChangedEvent ev, TeamFoundationRequestContext requestContext)
{
WorkItemStore wiStore = GetWorkItemStore(requestContext);
WorkItem witem = wiStore.GetWorkItem(ev.CoreFields.IntegerFields[0].NewValue);
Project teamProject = witem.Project;
int bugID = witem.Id;
string bugTitle = witem.Fields["System.Title"].Value.ToString();
string bugAssignedTo = witem.Fields["System.AssignedTo"].Value.ToString();
string bugAreaPath = witem.Fields["System.AreaPath"].Value.ToString();
string bugIterationPath = witem.Fields["System.IterationPath"].Value.ToString();
string bugChangedBy = witem.Fields["System.ChangedBy"].OriginalValue.ToString();
string bugTeamProject = witem.Project.Name;
string childTaskTitle = "Resolve bug " + bugID + " - " + bugTitle;
if (CreateResolutionTask(wiStore, bugID, childTaskTitle))
{
witem = CreateWorkItem(wiStore, teamProject, bugID, bugTitle, bugAssignedTo, bugAreaPath, bugIterationPath);
if (IsValid(witem))
{
witem.Save();
LinkParentAndChild(wiStore, witem, bugID);
}
}
}
private static bool IsValid(WorkItem witem)
{
ArrayList validationErrors = witem.Validate();
return validationErrors.Count == 0;
}
private static void LinkParentAndChild(WorkItemStore wiStore, WorkItem witem, int bugID)
{
var linkType = wiStore.WorkItemLinkTypes[CoreLinkTypeReferenceNames.Hierarchy];
var parentWorkItem = wiStore.GetWorkItem(bugID);
int taskID = witem.Id;
var childWorkItem = wiStore.GetWorkItem(taskID);
parentWorkItem.Links.Add(new WorkItemLink(linkType.ForwardEnd, childWorkItem.Id));
parentWorkItem.Save();
}
private static WorkItem CreateWorkItem(WorkItemStore wiStore, Project teamProject, int bugID, string bugTitle, string bugAssignedTo, string bugAreaPath, string bugIterationPath)
{
WorkItemTypeCollection workItemTypes = wiStore.Projects[teamProject.Name].WorkItemTypes;
WorkItemType wiType = workItemTypes["Task"];
WorkItem witem = new WorkItem(wiType);
witem.Fields["System.Title"].Value = "Resolve bug " + bugID + " - " + bugTitle;
witem.Fields["System.AssignedTo"].Value = bugAssignedTo;
witem.Fields["System.AreaPath"].Value = bugAreaPath;
witem.Fields["System.IterationPath"].Value = bugIterationPath;
witem.Fields["Microsoft.VSTS.Common.Activity"].Value = "Bug Resolution";
return witem;
}
private static bool CreateResolutionTask(WorkItemStore wiStore, int bugID, string childTaskTitle)
{
WorkItem parentBug = wiStore.GetWorkItem(bugID);
WorkItemLinkCollection links = parentBug.WorkItemLinks;
foreach (WorkItemLink wil in links)
{
if (wil.LinkTypeEnd.Name == "Child")
{
WorkItem childTask = wiStore.GetWorkItem(wil.TargetId);
if ((childTask.Title == childTaskTitle) && (childTask.State != "Closed"))
{
return false;
}
}
}
return true;
}
private static Uri GetTFSUri(TeamFoundationRequestContext requestContext)
{
var locationService = requestContext.GetService<TeamFoundationLocationService>();
return new Uri(locationService.GetServerAccessMapping(requestContext).AccessPoint + "/" + requestContext.ServiceHost.Name);
}
private static WorkItemStore GetWorkItemStore(TeamFoundationRequestContext requestContext)
{
NetworkCredential netCred = new NetworkCredential(
"<username>",
"<password>");
WindowsCredential windowsCred = new WindowsCredential(netCred);
var credentials = new TfsClientCredentials(windowsCred);
credentials.AllowInteractive = true;
var tpc = new TfsTeamProjectCollection(
GetTFSUri(requestContext),
credentials);
tpc.Authenticate();
return tpc.GetService<WorkItemStore>();
}
public Type[] SubscribedTypes()
{
return new Type[1] { typeof(WorkItemChangedEvent) };
}
}
}
Here is my full push notification listener.
public class MyApp extends UiApplication {
public static void main(String[] args) {
PushAgent pa = new PushAgent();
pa.enterEventDispatcher();
}
}
Is this class extended correctly?
public class PushAgent extends Application {
private static final String PUSH_PORT = "32023";
private static final String BPAS_URL = "http://pushapi.eval.blackberry.com";
private static final String APP_ID = "2727-c55087eR3001rr475448i013212a56shss2";
private static final String CONNECTION_SUFFIX = ";deviceside=false;ConnectionType=mds-public";
public static final long ID = 0x749cb23a75c60e2dL;
private MessageReadingThread messageReadingThread;
public PushAgent() {
if (!CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_BIS_B)) {
return;
}
if (DeviceInfo.isSimulator()) {
return;
}
messageReadingThread = new MessageReadingThread();
messageReadingThread.start();
registerBpas();
}
private static class MessageReadingThread extends Thread {
private boolean running;
private ServerSocketConnection socket;
private HttpServerConnection conn;
private InputStream inputStream;
private PushInputStream pushInputStream;
public MessageReadingThread() {
this.running = true;
}
public void run() {
String url = "http://:" + PUSH_PORT + CONNECTION_SUFFIX;
try {
socket = (ServerSocketConnection) Connector.open(url);
} catch (IOException ex) {
}
while (running) {
try {
Object o = socket.acceptAndOpen();
conn = (HttpServerConnection) o;
inputStream = conn.openInputStream();
pushInputStream = new MDSPushInputStream(conn, inputStream);
PushMessageReader.process(pushInputStream, conn);
} catch (Exception e) {
if (running) {
running = false;
}
} finally {
close(conn, pushInputStream, null);
}
}
}
}
public static void close(Connection conn, InputStream is, OutputStream os) {
if (os != null) {
try {
os.close();
} catch (IOException e) {
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
if (conn != null) {
try {
conn.close();
} catch (IOException e) {
}
}
}
private String formRegisterRequest(String bpasUrl, String appId,
String token) {
StringBuffer sb = new StringBuffer(bpasUrl);
sb.append("/mss/PD_subReg?");
sb.append("serviceid=").append(appId);
sb.append("&osversion=").append(DeviceInfo.getSoftwareVersion());
sb.append("&model=").append(DeviceInfo.getDeviceName());
if (token != null && token.length() > 0) {
sb.append("&").append(token);
}
return sb.toString();
}
private void registerBpas() {
final String registerUrl = formRegisterRequest(BPAS_URL, APP_ID, null)
+ CONNECTION_SUFFIX;
Object theSource = new Object() {
public String toString() {
return "Oriental Daily";
}
};
NotificationsManager.registerSource(ID, theSource,
NotificationsConstants.IMPORTANT);
new Thread() {
public void run() {
try {
HttpConnection httpConnection = (HttpConnection) Connector
.open(registerUrl);
InputStream is = httpConnection.openInputStream();
String response = new String(IOUtilities.streamToBytes(is));
close(httpConnection, is, null);
String nextUrl = formRegisterRequest(BPAS_URL, APP_ID,
response) + CONNECTION_SUFFIX;
HttpConnection nextHttpConnection = (HttpConnection) Connector
.open(nextUrl);
InputStream nextInputStream = nextHttpConnection
.openInputStream();
response = new String(
IOUtilities.streamToBytes(nextInputStream));
close(nextHttpConnection, is, null);
} catch (IOException e) {
}
}
}.start();
}
}
}
This is the process;
public class PushMessageReader {
private static final String MESSAGE_ID_HEADER = "Push-Message-ID";
private static final String MESSAGE_TYPE_TEXT = "text";
private static final String MESSAGE_TYPE_IMAGE = "image";
private static final int MESSAGE_ID_HISTORY_LENGTH = 10;
private static String[] messageIdHistory = new String[MESSAGE_ID_HISTORY_LENGTH];
private static byte historyIndex;
private static byte[] buffer = new byte[15 * 1024];
private static byte[] imageBuffer = new byte[10 * 1024];
public static final long ID = 0x749cb23a75c60e2dL;
public static Bitmap popup = Bitmap.getBitmapResource("icon_24.png");
private PushMessageReader() {
}
public static void process(PushInputStream pis, Connection conn) {
try {
HttpServerConnection httpConn;
if (conn instanceof HttpServerConnection) {
httpConn = (HttpServerConnection) conn;
} else {
throw new IllegalArgumentException(
"Can not process non-http pushes, expected HttpServerConnection but have "
+ conn.getClass().getName());
}
String msgId = httpConn.getHeaderField(MESSAGE_ID_HEADER);
String msgType = httpConn.getType();
String encoding = httpConn.getEncoding();
if (!alreadyReceived(msgId)) {
byte[] binaryData;
if (msgId == null) {
msgId = String.valueOf(System.currentTimeMillis());
}
if (msgType.indexOf(MESSAGE_TYPE_TEXT) >= 0) {
int size = pis.read(buffer);
binaryData = new byte[size];
System.arraycopy(buffer, 0, binaryData, 0, size);
NotificationsManager.triggerImmediateEvent(ID, 0, null,
null);
processTextMessage(buffer);
} else if (msgType.indexOf(MESSAGE_TYPE_IMAGE) >= 0) {
int size = pis.read(buffer);
if (encoding != null && encoding.equalsIgnoreCase("base64")) {
Base64InputStream bis = new Base64InputStream(
new ByteArrayInputStream(buffer, 0, size));
size = bis.read(imageBuffer);
}
binaryData = new byte[size];
System.arraycopy(buffer, 0, binaryData, 0, size);
}
}
pis.accept();
} catch (Exception e) {
} finally {
PushAgent.close(conn, pis, null);
}
}
private static boolean alreadyReceived(String id) {
if (id == null) {
return false;
}
if (Arrays.contains(messageIdHistory, id)) {
return true;
}
messageIdHistory[historyIndex++] = id;
if (historyIndex >= MESSAGE_ID_HISTORY_LENGTH) {
historyIndex = 0;
}
return false;
}
private static void processTextMessage(final byte[] data) {
synchronized (Application.getEventLock()) {
UiEngine ui = Ui.getUiEngine();
GlobalDialog screen = new GlobalDialog("New Notification",
"Article ID : " + new String(data), new String(data));
ui.pushGlobalScreen(screen, 1, UiEngine.GLOBAL_QUEUE);
}
}
static class GlobalDialog extends PopupScreen implements
FieldChangeListener {
ButtonField mOKButton = new ButtonField("OK", ButtonField.CONSUME_CLICK
| FIELD_HCENTER);
String data = "";
public GlobalDialog(String title, String text, String data) {
super(new VerticalFieldManager());
this.data = data;
add(new LabelField(title));
add(new SeparatorField(SeparatorField.LINE_HORIZONTAL));
add(new LabelField(text, DrawStyle.HCENTER));
mOKButton.setChangeListener(this);
add(mOKButton);
}
public void fieldChanged(Field field, int context) {
if (mOKButton == field) {
try {
ApplicationManager.getApplicationManager().launch(
"OrientalDailyBB");
ApplicationManager.getApplicationManager().postGlobalEvent(
ID, 0, 0, data, null);
ApplicationIndicatorRegistry reg = ApplicationIndicatorRegistry
.getInstance();
reg.unregister();
close();
} catch (ApplicationManagerException e) {
}
}
}
}
}
In this project, I checked Auto-run on startup so that this background app listener will run all the time and set the start tier to 7 in the BB App Descriptor.
However, it cannot display the popup Dialog, but I can see the device has received the push notification.
After the dialog popup and user click OK will start the OrientalDailyBB project and display the particular MainScreen.
FYI: The listener priority is higher than the OrientalDailyBB project because it is a background application. So when I install OrientalDailyBB, it will install this listener too. It happened because this listener is not in the OrientalDailyBB project folder, but is in a different folder. I did separate them to avoid the background application being terminated when the user quits from OrientalDailyBB.
I believe that this is a threading problem. pushGlobalScreen is a message you could try to use with invokeLater.
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
ui.pushGlobalScreen(screen, 1, UiEngine.GLOBAL_QUEUE);
}
});
you could try to push the application to the foreground too.
I am working on an email client that will connect to Gmail mailbox and retrieve a specific email.
Now i can connect to my mailbox and can retrieve part of the emails not all of it and no matter how large is my buffer still i get only 1400 char from my email and then Null for the rest of the mail body.
You can find a screen shot for the email body in this link
http://www.elzouhery.com/Mail%20Snapshot.png
Thanks in Advance
EDIT
See below the Full Code
static void Main(string[] args)
{
TcpIMAP imap = ConnectToEmail();
Console.WriteLine("Total Messages " + imap.MailCount());
Console.WriteLine("Total Unread Messages " + imap.MailUnreadCount());
Console.WriteLine("******************************************************");
imap.SelectInbox();
StreamWriter writer = null;
int mailCount = imap.MailCount();
var mailSize = string.Empty;
var content = string.Empty;
var subject = string.Empty;
for (int i = 1; i < mailCount; i++)
{
try
{
writer = new StreamWriter(#"c:\Mails\" + i + ".txt", true);
content = imap.GetMessage(i).ToString();
writer.Write(content);
writer.Close();
}
catch(Exception ex)
{
writer.Write(content);
Console.Write(ex.Message);
writer.Close();
}
}
}
private static TcpIMAP ConnectToEmail()
{
string host = "imap.gmail.com";
string username = "************";
string password = "************";
TcpIMAP imap = new TcpIMAP();
imap.Connect(host, 993);
imap.AuthenticateUser(username, password);
return imap;
}
public static string GetMailSubject(string Header)
{
var headerLines = Header.Split(Environment.NewLine.ToCharArray());
foreach (var line in headerLines)
{
if (line.IndexOf("Subject") > -1)
{
return line.Replace("Subject: ", "");
}
}
return "";
}
/***************************************************/
class TcpIMAP
{
private TcpClient _imapClient;
private Stream _imapNs;
private StreamWriter _imapSw;
private StreamReader _imapSr;
public TcpIMAP()
{
}
public TcpIMAP(string hostname, int port)
{
InitializeConnection(hostname, port);
}
public void Connect(string hostname, int port)
{
InitializeConnection(hostname, port);
}
private void InitializeConnection(string hostname, int port)
{
try
{
_imapClient = new TcpClient(hostname, port);
System.Net.Security.SslStream sslstream = new System.Net.Security.SslStream(_imapClient.GetStream());
sslstream.AuthenticateAsClient("imap.gmail.com");
_imapNs = sslstream;
_imapSw = new StreamWriter(_imapNs);
_imapSr = new StreamReader(_imapNs);
Console.WriteLine("*** Connected ***");
Response();
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
}
}
public void AuthenticateUser(string username, string password)
{
_imapSw.WriteLine("$ LOGIN " + username + " " + password);
_imapSw.Flush();
Response();
}
public int MailCount()
{
_imapSw.WriteLine("$ STATUS INBOX (messages)");
_imapSw.Flush();
string res = Response();
Match m = Regex.Match(res, "[0-9]*[0-9]");
return Convert.ToInt32(m.ToString());
}
public int MailUnreadCount()
{
_imapSw.WriteLine("$ STATUS INBOX (unseen)");
_imapSw.Flush();
string res = Response();
Match m = Regex.Match(res, "[0-9]*[0-9]");
return Convert.ToInt32(m.ToString());
}
public string SelectInbox()
{
_imapSw.WriteLine("$ SELECT INBOX");
_imapSw.Flush();
return Response();
}
public object GetMessageHeaders(int index)
{
_imapSw.WriteLine("$ FETCH " + index + " (body[header.fields (from subject date)])");
_imapSw.Flush();
return Response();
}
public object GetMessage(int index)
{
_imapSw.WriteLine("$ FETCH " + index + " BODY.PEEK[]");
_imapSw.Flush();
return Response();
}
private string Response()
{
byte[] data = new byte[_imapClient.ReceiveBufferSize];
int ret = _imapNs.Read(data, 0, data.Length);
string output = Encoding.ASCII.GetString(data).TrimEnd().Replace("\0", "");
return output;
}
public void Disconnect()
{
_imapSw.WriteLine("$ LOGOUT");
_imapSw.Flush();
_imapClient.Close();
}
public string SendCommand(string command)
{
_imapSw.WriteLine("$ " + command);
_imapSw.Flush();
return Response();
}
It looks like you are using code from here, or similar:
http://www.codeproject.com/Articles/29594/How-to-Access-Emails-Using-the-IMAP-Protocol
That code as written is wrong and won't work for larger messages. The Response() call needs to loop over calls to .Read(), appending the results until the method returns 0 (which indicates there is no more data available.) Look at the documentation for NetworkStream.Read.
Also, you'd be much better off using an IMAP library (see Accessing Imap in C#).
You Just Have To Change Your Receive Buffer Size