EJB timer not execute job - timer

The execution is not launching any scheduled job.
Is it something left?
Environment:
Java 8
Javaee 7
Wildfly 10
Job
#Singleton
public class TimerJob {
protected Logger logger = Logger.getLogger(getClass().getName());
#Schedule(hour = "23", minute = "59", persistent = true, info = "Hello programades")
public void execute() {
logger.info("Timer Job execution " + new Date());
}
#Schedule(second = "*/5", persistent = false, info = "Prova de programació")
public void executeTest() {
logger.info("Actuacio Job execution TEST" + new Date());
}
}

Ensure that you're using #javax.ejb.Singleton rather than #javax.inject.Singleton;
Add #javax.ejb.Startup to your class declaration otherwise then bean will not exist until you reference it from somewhere else.

Related

ABP framework / parallel programming

I have one AsyncPeriodicBackgroundWorkerBase base class(DataValidateWorker) which runs 1 minute interval.
I need to send the data I get from the DB to a third party web service and update the results in the db. A Web service response arrives in about 30-40 seconds. For this reason, I need to send Web service queries simultaneously, not sequentially.
For this reason, I wrote code in accordance with parallel programming as seen below. I cannot pull the database connection for the Task I wrote. DB connection closed, I got many errors like Executing.
How can I create the db connection for my Task?
Would it be better to write this job in an external application (exe or service) instead of ABP?
public class DataValidateWorker : AsyncPeriodicBackgroundWorkerBase
{
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IDataFilter _dataFilter;
public DataValidateWorker(AbpAsyncTimer timer, IServiceScopeFactory serviceScopeFactory, IDataFilter dataFilter, IUnitOfWorkManager unitOfWorkManager) : base(timer, serviceScopeFactory)
{
_dataFilter = dataFilter;
_unitOfWorkManager = unitOfWorkManager;
Timer.Period = 60 * 1000; // 60 seconds
}
[UnitOfWork]
protected async override Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
{
try
{
var notificationValidationRepository = workerContext.ServiceProvider.GetRequiredService<IRepository<NotificationValidation, int>>();
var notificationValidationItems = await notificationValidationRepository.GetQueryableAsync();
List<NotificationValidation> list = new List<NotificationValidation>();
using (var uow = _unitOfWorkManager.Begin())
{
using (_dataFilter.Disable<IMultiTenant>())
{
list = notificationValidationItems.Where(x => x.RecordDateTime <= DateTime.Now && x.ValidationResult == (int)ValidationResult.NotStarted).ToList();
}
}
NotificationValidationArgs jobArgs = new NotificationValidationArgs();
foreach (var item in list)
{
jobArgs.notificationValidationId = item.Id;
Task taskA = Task.Factory.StartNew(async (Object obj) =>
{
// doing some third party web service operations and db operations
}, jobArgs);
}
}
catch (Exception ex)
{
Logger.LogCritical(2001, ex, DateTime.Now.ToString() + " -> DataValidateWorker -> try 1 -> RDMS uow");
}
}
}
You don't await any of tasks, so lifetime of object ends while your task is still running.
Try to store all of the tasks in a collection and await them before method execution finishes.
Something like below:
public class DataValidateWorker : AsyncPeriodicBackgroundWorkerBase
{
public DataValidateWorker(AbpAsyncTimer timer, IServiceScopeFactory serviceScopeFactory) : base(timer, serviceScopeFactory)
{
}
protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
{
var tasks = new List<Task>();
foreach (var item in list)
{
tasks.Add(YourLongJob(arg)); // don't await here. collect in a collection
}
await Task.WhenAll(tasks); // wait until all of them is completed.
}
private async Task YourLongJob(object arg)
{
await Task.Delay(30 * 1000); // a long job
}
}

Adding and using Multiple Connectionstrings in .net core

I am new to .Net Core - I need to add 2 connectionstrings (One for test db and one for live db), and want to connect to both - i.e. connect to live db and transfer data over to test db. Below is my appsettings.json:
{
"ConnectionStrings": {
"DefaultConnection": "Server=PC\\SQLEXPRESS;Database=[DB];User Id=[Username];Password=[Password];",
"MarkingManagerLIVEConnection": "Server=[IP];Database=[DB];User Id=[Username];Password=[Password]"
},
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}
I believe I need to register this:
private static void RegisterDatabase(IServiceCollection services, IConfiguration config)
{
services.AddDbContext<MarkingManagerDbContext>(options => options.UseSqlServer(config.GetConnectionString("DefaultConnection")));
services.AddDbContext<MarkingManagerDbContext>(liveoptions => liveoptions.UseSqlServer(config.GetConnectionString("MarkingManagerLIVEConnection")));
}
This is what is on the console apps Main:
static void Main(string[] args)
{
Console.Write("Register Services");
var services = new ServiceCollection();
RegisterServices.Register(services);
Console.WriteLine("=>Done");
_services = services.BuildServiceProvider();
Console.Write("DB Configuration");
var context = _services.GetRequiredService<MarkingManagerDbContext>();
var mmSeed = _services.GetRequiredService<MarkingManagerSeed>();
if (context.Database.EnsureCreated())
{
context.Database.Migrate();
var mmSeedTesk = mmSeed.Seed();
mmSeedTesk.Wait();
}
Console.WriteLine("=>Done");
Console.WriteLine("Press any key to end the process");
Console.ReadLine();
}
How do I make use of the "Live" Connectionstring ? Or am I missing something?
Thanks for any help!

Apache Camel - Create a custom Component/Endpoint?

I need to consume messages from a Websocket, but I have to do some logics before consume the data, so I can't use Webscoket Component.
I have a java code that do Authentication in this Websocket and subscribe a "Sensor" to receive data.
Can I create a Camel Component that I use this code in from() and every time I receive new data onNext() the Camel starts the process?
WebSocket webSocket = new WebSocket(uri, apiKey, (api, authenthication) -> {
console.println("Authenticated successfully as " + authenthication.getUserName());
String[] sensors = {sensorId};
api.getMetrics(sensors).subscribe(metrics -> {
Metric[] allMetrics = metrics.get(sensorId);
Arrays.sort(allMetrics, (metric1, metric2) -> metric1.getId().compareTo(metric2.getId()));
Metric firstMetric = allMetrics[0];
console.println("Metric: " + firstMetric.getDisplayName());
String metricId = firstMetric.getId();
String[] metric = {metricId};
api.getUnits(metric).subscribe(units -> {
Unit unit = units.get(metric[0])[0];
console.println("Unit: " + unit.getName());
Instant now = Instant.now();
Instant aMinuteAgo = now.minus(timeInterval, ChronoUnit.SECONDS);
Date start = Date.from(aMinuteAgo);
Date end = Date.from(now);
api.getData(sensorId, metricId, unit.getId(), emptyMap(), start, end).subscribe(new DisposableObserver<Data>() {
#Override
public void onNext(Data data) {
console.println("Data from last " + timeInterval + " seconds: ");
console.println(data.getData());
}
#Override
public void onComplete() {
console.println("Data update:");
Disposable subscription = api.subscribeData(sensors, metricId, unit.getId()).subscribe(updates -> {
console.println(updates.getData());
});
ScheduledExecutorService scheduler = newSingleThreadScheduledExecutor(daemonThreadFactory);
scheduler.schedule(subscription::dispose, cancelDelay, SECONDS);
}
#Override
public void onError(Throwable error) {
error.printStackTrace();
}
});
});
});
});
console.println("Connection was closed by server.");
}

handling events that do not generate alerts in Apache Flink

I'm using Flink CEP and I need to handle even events that do not generate alerts. Please how can I do it?
I'm consuming events from rabbitMq and have defined some patterns. Now what I need to do is to send all the events received in another Queue to a distant API. I'm new at Flink so I followed the example in the documentation. When I try to send them after matching the received events with the patterns defined I only get those how match with the patterns. What I want to do is just to put an attribute to true in my events for example and send them all to the output queue.
public static void cep() throws Exception {
/**
* RabbitMQ connection
*/
final RMQConnectionConfig connectionConfig = new RMQConnectionConfig.Builder()
.setHost(HOST)
.setPort(PORTS[RD.getValue()])
.setUserName("guest")
.setPassword("guest")
.setVirtualHost("/")
.build();
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
/**
* Retrieve data inputEventstream from rabbitMQ
*/
final DataStream<String> inputEventstream = env
.addSource(new RMQSource<>(
connectionConfig, // config for the RabbitMQ connection
"input", // name of the RabbitMQ queue to consume
true, // use correlation ids; can be false if only at-least-once is required
new SimpleStringSchema())) // deserialization schema to turn messages into Java objects
.setParallelism(1);
/**
* Change DataStream<String> to DataStream<MonitoringEvent> where
* MonitoringEvent refer to a class which modelize our event.
*/
DataStream<MonitoringEvent> inputEventStreamClean = inputEventstream.flatMap(new Tokenizer());
Pattern<MonitoringEvent, ?> warningPattern = Pattern.<MonitoringEvent>begin("start")
.subtype(MonitoringEvent.class)
.where(new SimpleCondition<MonitoringEvent>() {
#Override
public boolean filter(MonitoringEvent value) {
return Integer.parseInt(value.getAncienneChute())>=CHUTE_GRAVE;
}
}).or(new SimpleCondition<MonitoringEvent>() {
#Override
public boolean filter(MonitoringEvent value) {
return value.isChaiseRoulante();
}
}).or(new SimpleCondition<MonitoringEvent>() {
#Override
public boolean filter(MonitoringEvent value) {
return value.isDeambulateur();
}
}).or(new SimpleCondition<MonitoringEvent>() {
#Override
public boolean filter(MonitoringEvent value) {
return value.isDeambulateur();
}
})
.or(new SimpleCondition<MonitoringEvent>() {
#Override
public boolean filter(MonitoringEvent value) {
return EntityManager.getInstance().hasCurrentYearFallTwice(value.getIdClient());
}
});
//PatternStream<MonitoringEvent> fallPatternStream = CEP.pattern(inputEventStreamClean.keyBy("idClient"), warningPattern);
inputEventStreamClean.print();
// Create a pattern stream from our warning pattern
PatternStream<MonitoringEvent> tempPatternStream = CEP.pattern(
inputEventStreamClean.keyBy("idClient"),
warningPattern);
DataStream<FallWarning> warnings = tempPatternStream.select(
(Map<String, List<MonitoringEvent>> pattern) -> {
MonitoringEvent first = (MonitoringEvent) pattern.get("start").get(0);
return new FallWarning(first.getIdClient(), Integer.valueOf(first.getAncienneChute()));
}
);
// Alert pattern: Two consecutive temperature warnings appearing within a time interval of 20 seconds
Pattern<FallWarning, ?> alertPattern = Pattern.<FallWarning>begin("start");
// Create a pattern stream from our alert pattern
PatternStream<FallWarning> alertPatternStream = CEP.pattern(
//warnings.keyBy("idClient"),
warnings,
alertPattern);
// Generate alert
DataStream<Alert> alerts = alertPatternStream.flatSelect(
(Map<String, List<FallWarning>> pattern, Collector<Alert> out) -> {
FallWarning first = pattern.get("start").get(0);
if (first.idNiveauUrgence>=CHUTE_GRAVE && (first.isChaiseRoulante() || first.isDeambulateur() || first.isFracture())) {
out.collect(new Alert(first.idClient));
}
});
// Print the warning and alert events to stdout
warnings.print();
alerts.print(); // here I can send them to RabbitMq
env.execute();
}
You just need to add a Sink to your "alert" DataStream like
alert.addSink(new RMQSink<String>(
connectionConfig, // config for the RabbitMQ connection
"queueName", // name of the RabbitMQ queue to send messages to
new SimpleStringSchema())); // serialization schema to turn Java objects to messages
per example at
https://ci.apache.org/projects/flink/flink-docs-release-1.2/dev/connectors/rabbitmq.html

How to unit test Soap service access from Crm 2011 Silverlight application?

In a Silverlight 5 application in Dynamics CRM 2011 I access the Organization Service of the CRM to query for entity Metadata. I wrote a service that takes an entity name and returns a list of all its fields.
How can I test this service method automatically? The main problem is how to obtain a reference to the organization service from a Silverlight app that does not run in the context of the CRM.
My Service method looks like this:
public IOrganizationService OrganizationService
{
get
{
if (_organizationService == null)
_organizationService = SilverlightUtility.GetSoapService();
return _organizationService;
}
set { _organizationService = value; }
}
public async Task<List<string>> GetAttributeNamesOfEntity(string entityName)
{
// build request
OrganizationRequest request = new OrganizationRequest
{
RequestName = "RetrieveEntity",
Parameters = new ParameterCollection
{
new XrmSoap.KeyValuePair<string, object>()
{
Key = "EntityFilters",
Value = EntityFilters.Attributes
},
new XrmSoap.KeyValuePair<string, object>()
{
Key = "RetrieveAsIfPublished",
Value = true
},
new XrmSoap.KeyValuePair<string, object>()
{
Key = "LogicalName",
Value = "avobase_tradeorder"
},
new XrmSoap.KeyValuePair<string, object>()
{
Key = "MetadataId",
Value = new Guid("00000000-0000-0000-0000-000000000000")
}
}
};
// fire request
IAsyncResult result = OrganizationService.BeginExecute(request, null, OrganizationService);
// wait for response
TaskFactory<OrganizationResponse> tf = new TaskFactory<OrganizationResponse>();
OrganizationResponse response = await tf.FromAsync(
OrganizationService.BeginExecute(request, null, null), iar => OrganizationService.EndExecute(result));
// parse response
EntityMetadata entities = (EntityMetadata)response["EntityMetadata"];
return entities.Attributes.Select(attr => attr.LogicalName).ToList();
}
Edit:
I can create and execute unit tests with Resharper and AgUnit. Thus, the problem is not how to write a unit test in general.
I have tweaked the GetSoapService from the standard Microsoft SDK to accept a fall back value. This means no codes changes are needed when debugging in visual studio and running in CRM. Anyway here it is
public static IOrganizationService GetSoapService(string FallbackValue = null)
{
Uri serviceUrl = new Uri(GetServerBaseUrl(FallbackValue)+ "/XRMServices/2011/Organization.svc/web");
BasicHttpBinding binding = new BasicHttpBinding(Uri.UriSchemeHttps == serviceUrl.Scheme
? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.TransportCredentialOnly);
binding.MaxReceivedMessageSize = int.MaxValue;
binding.MaxBufferSize = int.MaxValue;
binding.SendTimeout = TimeSpan.FromMinutes(20);
IOrganizationService ser =new OrganizationServiceClient(binding, new EndpointAddress(serviceUrl));
return ser;
}
public static string GetServerBaseUrl(string FallbackValue = null)
{
try
{
string serverUrl = (string)GetContext().Invoke("getClientUrl");
//Remove the trailing forwards slash returned by CRM Online
//So that it is always consistent with CRM On Premises
if (serverUrl.EndsWith("/"))
{
serverUrl = serverUrl.Substring(0, serverUrl.Length - 1);
}
return serverUrl;
}
catch
{
//Try the old getServerUrl
try
{
string serverUrl = (string)GetContext().Invoke("getServerUrl");
//Remove the trailing forwards slash returned by CRM Online
//So that it is always consistent with CRM On Premises
if (serverUrl.EndsWith("/"))
{
serverUrl = serverUrl.Substring(0, serverUrl.Length - 1);
}
return serverUrl;
}
catch
{
return FallbackValue;
}
}

Resources