You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2020/09/19 13:34:37 UTC
[isis] 02/03: ISIS-2222: reworking Command and other stuff
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch ISIS-2222
in repository https://gitbox.apache.org/repos/asf/isis.git
commit 1b3db60272e34b0ec8911a8c24e65639e601e8ab
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Mon Sep 14 15:49:29 2020 +0100
ISIS-2222: reworking Command and other stuff
---
.../org/apache/isis/applib/IsisModuleApplib.java | 4 +-
.../org/apache/isis/applib/annotation/Action.java | 6 +-
.../apache/isis/applib/annotation/Property.java | 6 +-
.../isis/applib/services/command/Command.java | 3 +-
.../applib/services/commanddto/HasCommandDto.java | 12 ++
.../conmap/ContentMappingServiceForCommandDto.java | 106 ++++++++++++++
.../ContentMappingServiceForCommandsDto.java | 2 +-
.../conmap}/UserDataKeys.java | 2 +-
.../processor}/CommandDtoProcessor.java | 33 +++--
.../CommandDtoProcessorForActionAbstract.java | 6 +-
.../CommandDtoProcessorForPropertyAbstract.java | 6 +-
.../processor}/spi/CommandDtoProcessorService.java | 19 ++-
.../ContentMappingServiceForCommandDto.java | 153 ---------------------
.../services/metamodel/MetaModelService.java | 6 +-
.../apache/isis/core/config/IsisConfiguration.java | 90 ++++++------
.../config/application-secondary.properties | 7 +-
examples/demo/web/pom.xml | 6 +-
.../src/main/java/demoapp/web/DemoAppManifest.java | 8 +-
.../wicket/src/main/resources/log4j2-spring.xml | 2 +-
.../extensions/commandlog/impl/jdo/CommandJdo.java | 9 +-
.../commandlog/impl/jdo/CommandJdoRepository.java | 6 +-
.../commandreplay/impl/fetch/PrimaryConfig.java | 38 -----
.../commandreplay/impl/fetch/SecondaryConfig.java | 32 -----
.../impl/mixins/CommandJdo_openOnPrimary.java | 57 --------
.../impl/mixins/CommandJdo_replayQueue.java | 47 -------
extensions/core/command-replay/pom.xml | 3 +-
.../core/command-replay/{impl => primary}/pom.xml | 16 +--
.../primary/IsisModuleExtCommandReplayPrimary.java | 33 +++++
.../primary}/mixins/CommandJdo_download.java | 27 ++--
.../primary/spiimpl/CaptureResultOfCommand.java | 62 +++++++++
.../primary}/ui/CommandReplayOnPrimaryService.java | 39 ++++--
.../command-replay/{impl => secondary}/pom.xml | 8 +-
.../IsisModuleExtCommandReplaySecondary.java} | 34 ++---
.../commandreplay/secondary}/SecondaryStatus.java | 2 +-
.../commandreplay/secondary}/StatusException.java | 2 +-
.../secondary/analyser}/CommandReplayAnalyser.java | 2 +-
.../analyser}/CommandReplayAnalyserException.java | 17 ++-
.../analyser}/CommandReplayAnalyserResult.java | 17 ++-
.../analysis/CommandReplayAnalysisService.java | 12 +-
.../secondary}/clock/TickingClockService.java | 33 +++--
.../secondary/config/SecondaryConfig.java | 54 ++++++++
.../executor/CommandExecutorServiceWithTime.java | 22 +--
.../secondary}/fetch/CommandFetcher.java | 50 ++++---
.../secondary}/job/ReplicateAndReplayJob.java | 16 +--
.../secondary}/job/SecondaryStatusData.java | 4 +-
.../jobcallables}/IsTickingClockInitialized.java | 4 +-
.../jobcallables}/ReplicateAndRunCommands.java | 96 +++++++------
.../secondary}/mixins/CommandJdo_exclude.java | 23 ++--
.../secondary/mixins/CommandJdo_openOnPrimary.java | 54 ++++++++
.../secondary}/mixins/CommandJdo_replayNext.java | 45 +++---
.../secondary/mixins/CommandJdo_replayQueue.java | 42 ++++++
.../spi/ReplayCommandExecutionController.java | 2 +-
.../ui/CommandReplayOnSecondaryService.java | 23 ++--
.../secondary/fetch/CommandFetcher_Test.java} | 8 +-
extensions/pom.xml | 8 +-
.../impl/client/JaxRsClientDefault.java | 9 +-
.../viewer/resources/ObjectActionArgHelper.java | 10 +-
57 files changed, 776 insertions(+), 667 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/isis/applib/IsisModuleApplib.java b/api/applib/src/main/java/org/apache/isis/applib/IsisModuleApplib.java
index c68a0b5..fd7732e 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/IsisModuleApplib.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/IsisModuleApplib.java
@@ -36,8 +36,8 @@ import org.apache.isis.applib.services.clock.ClockService;
import org.apache.isis.applib.services.command.CommandContext;
import org.apache.isis.applib.services.command.CommandService;
import org.apache.isis.applib.services.confview.ConfigurationMenu;
-import org.apache.isis.applib.services.conmap.command.ContentMappingServiceForCommandDto;
-import org.apache.isis.applib.services.conmap.command.ContentMappingServiceForCommandsDto;
+import org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandDto;
+import org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandsDto;
import org.apache.isis.applib.services.iactn.InteractionContext;
import org.apache.isis.applib.services.jaxb.JaxbServiceDefault;
import org.apache.isis.applib.services.layout.LayoutServiceMenu;
diff --git a/api/applib/src/main/java/org/apache/isis/applib/annotation/Action.java b/api/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
index 12583cd..f8c0703 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
@@ -26,10 +26,10 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.isis.applib.events.domain.ActionDomainEvent;
-import org.apache.isis.applib.services.command.CommandDtoProcessor;
+import org.apache.isis.applib.services.commanddto.processor.CommandDtoProcessor;
import org.apache.isis.applib.services.command.CommandService;
-import org.apache.isis.applib.services.conmap.command.ContentMappingServiceForCommandDto;
-import org.apache.isis.applib.services.conmap.command.ContentMappingServiceForCommandsDto;
+import org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandDto;
+import org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandsDto;
import org.apache.isis.applib.value.Blob;
import org.apache.isis.applib.value.Clob;
diff --git a/api/applib/src/main/java/org/apache/isis/applib/annotation/Property.java b/api/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
index 5393e2c..65db374 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
@@ -26,9 +26,9 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.isis.applib.events.domain.PropertyDomainEvent;
-import org.apache.isis.applib.services.command.CommandDtoProcessor;
-import org.apache.isis.applib.services.conmap.command.ContentMappingServiceForCommandDto;
-import org.apache.isis.applib.services.conmap.command.ContentMappingServiceForCommandsDto;
+import org.apache.isis.applib.services.commanddto.processor.CommandDtoProcessor;
+import org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandDto;
+import org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandsDto;
import org.apache.isis.applib.spec.Specification;
import org.apache.isis.applib.value.Blob;
import org.apache.isis.applib.value.Clob;
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/command/Command.java b/api/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
index 5967960..c7e11e4 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
@@ -25,6 +25,7 @@ import org.apache.isis.applib.events.domain.ActionDomainEvent;
import org.apache.isis.applib.services.HasUniqueId;
import org.apache.isis.applib.services.HasUsername;
import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.commanddto.HasCommandDto;
import org.apache.isis.applib.services.iactn.Interaction;
import org.apache.isis.applib.services.wrapper.WrapperFactory;
import org.apache.isis.applib.services.wrapper.control.AsyncControl;
@@ -67,7 +68,7 @@ import lombok.Getter;
* </p>
*/
// tag::refguide[]
-public class Command implements HasUniqueId, HasUsername {
+public class Command implements HasUniqueId, HasUsername, HasCommandDto {
public Command() {
this(UUID.randomUUID());
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/HasCommandDto.java b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/HasCommandDto.java
new file mode 100644
index 0000000..6c9d631
--- /dev/null
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/HasCommandDto.java
@@ -0,0 +1,12 @@
+package org.apache.isis.applib.services.commanddto;
+
+import org.apache.isis.schema.cmd.v2.CommandDto;
+
+/**
+ * Objects implementing this interface will be processed automatically by
+ * {@link org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandDto}.
+ */
+public interface HasCommandDto {
+
+ CommandDto getCommandDto();
+}
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/conmap/ContentMappingServiceForCommandDto.java b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/conmap/ContentMappingServiceForCommandDto.java
new file mode 100644
index 0000000..6e1edfb
--- /dev/null
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/conmap/ContentMappingServiceForCommandDto.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) 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.apache.isis.applib.services.commanddto.conmap;
+
+import java.sql.Timestamp;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.ws.rs.core.MediaType;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Primary;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
+
+import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.commanddto.HasCommandDto;
+import org.apache.isis.applib.services.commanddto.processor.CommandDtoProcessor;
+import org.apache.isis.applib.services.conmap.ContentMappingService;
+import org.apache.isis.applib.services.commanddto.processor.spi.CommandDtoProcessorService;
+import org.apache.isis.applib.services.metamodel.MetaModelService;
+import org.apache.isis.applib.util.schema.CommandDtoUtils;
+import org.apache.isis.core.commons.internal.exceptions._Exceptions;
+import org.apache.isis.schema.cmd.v2.CommandDto;
+import org.apache.isis.schema.common.v2.PeriodDto;
+
+import lombok.val;
+
+@Service
+@Named("isisApplib.ContentMappingServiceForCommandDto")
+@Order(OrderPrecedence.EARLY)
+@Primary
+@Qualifier("CommandDto")
+public class ContentMappingServiceForCommandDto implements ContentMappingService {
+
+ @Override
+ public Object map(Object object, final List<MediaType> acceptableMediaTypes) {
+ final boolean supported = Util.isSupported(CommandDto.class, acceptableMediaTypes);
+ if(!supported) {
+ return null;
+ }
+
+ return asProcessedDto(object);
+ }
+
+ CommandDto asProcessedDto(final Object object) {
+ val commandDto = asCommandDto(object);
+ return asProcessedDto(object, commandDto);
+ }
+
+ private CommandDto asCommandDto(Object object) {
+ if(object instanceof CommandDto) {
+ return (CommandDto) object;
+ }
+ if(object instanceof HasCommandDto) {
+ return ((HasCommandDto) object).getCommandDto();
+ }
+ return null;
+ }
+
+ private CommandDto asProcessedDto(final Object domainObject, CommandDto commandDto) {
+
+ // global processors
+ for (final CommandDtoProcessorService commandDtoProcessorService : commandDtoProcessorServices) {
+ commandDto = commandDtoProcessorService.process(domainObject, commandDto);
+ if(commandDto == null) {
+ // any processor could return null, effectively breaking the chain.
+ return null;
+ }
+ }
+
+ // specific processor for this specific member (action or property)
+ val logicalMemberId = commandDto.getMember().getLogicalMemberIdentifier();
+ final CommandDtoProcessor commandDtoProcessor =
+ metaModelService.commandDtoProcessorFor(logicalMemberId);
+ if (commandDtoProcessor == null) {
+ return commandDto;
+ }
+ return commandDtoProcessor.process(commandDto);
+ }
+
+
+ @Inject MetaModelService metaModelService;
+ @Inject List<CommandDtoProcessorService> commandDtoProcessorServices;
+
+}
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/conmap/command/ContentMappingServiceForCommandsDto.java b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/conmap/ContentMappingServiceForCommandsDto.java
similarity index 98%
rename from api/applib/src/main/java/org/apache/isis/applib/services/conmap/command/ContentMappingServiceForCommandsDto.java
rename to api/applib/src/main/java/org/apache/isis/applib/services/commanddto/conmap/ContentMappingServiceForCommandsDto.java
index ade5070..4d491b2 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/conmap/command/ContentMappingServiceForCommandsDto.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/conmap/ContentMappingServiceForCommandsDto.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.isis.applib.services.conmap.command;
+package org.apache.isis.applib.services.commanddto.conmap;
import java.util.List;
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/conmap/command/UserDataKeys.java b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/conmap/UserDataKeys.java
similarity index 95%
rename from api/applib/src/main/java/org/apache/isis/applib/services/conmap/command/UserDataKeys.java
rename to api/applib/src/main/java/org/apache/isis/applib/services/commanddto/conmap/UserDataKeys.java
index bc1bb2f..4fc4e59 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/conmap/command/UserDataKeys.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/conmap/UserDataKeys.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.isis.applib.services.conmap.command;
+package org.apache.isis.applib.services.commanddto.conmap;
import org.apache.isis.schema.cmd.v2.CommandDto;
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/command/CommandDtoProcessor.java b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/processor/CommandDtoProcessor.java
similarity index 57%
rename from api/applib/src/main/java/org/apache/isis/applib/services/command/CommandDtoProcessor.java
rename to api/applib/src/main/java/org/apache/isis/applib/services/commanddto/processor/CommandDtoProcessor.java
index 60edc81..a0706ad 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/command/CommandDtoProcessor.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/processor/CommandDtoProcessor.java
@@ -16,33 +16,42 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.isis.applib.services.command;
+package org.apache.isis.applib.services.commanddto.processor;
import org.apache.isis.schema.cmd.v2.CommandDto;
+/**
+ * Refine (or possibly ignore) a command when replicating from primary
+ * to secondary.
+ */
// tag::refguide[]
public interface CommandDtoProcessor {
// end::refguide[]
/**
- * Returning <tt>null</tt> means that the command's DTO is effectively excluded from any list.
- * If replicating from master to slave, this allows commands that can't be replicated to be ignored.
- * @param command
- * @param commandDto
+ * The implementation can if necessary refine or alter the
+ * {@link CommandDto} to be replicated from primary to secondary.
+ *
+ * <p>
+ * That said, the most common use case is to return <code>null</code>,
+ * which results in the command effectively being ignore.
+ * </p>
+ *
+ * @param commandDto - to be processed
+ * @return <tt>null</tt> means that the command's DTO is effectively
+ * excluded.
*/
// tag::refguide[]
- CommandDto process(final Command command, CommandDto commandDto); // <.>
+ CommandDto process(CommandDto commandDto); // <.>
// end::refguide[]
/**
- * Convenience implementation to simply indicate that no DTO should be returned for a command,
- * effectively ignoring it for replay purposes.
+ * Convenience implementation to simply indicate that no DTO should be
+ * returned for a command, effectively ignoring it for replication purposes.
*/
- public static class Null implements CommandDtoProcessor {
+ class Null implements CommandDtoProcessor {
@Override
- public CommandDto process(
- final Command command,
- final CommandDto commandDto) {
+ public CommandDto process(final CommandDto commandDto) {
return null;
}
}
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/command/CommandDtoProcessorForActionAbstract.java b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/processor/CommandDtoProcessorForActionAbstract.java
similarity index 91%
rename from api/applib/src/main/java/org/apache/isis/applib/services/command/CommandDtoProcessorForActionAbstract.java
rename to api/applib/src/main/java/org/apache/isis/applib/services/commanddto/processor/CommandDtoProcessorForActionAbstract.java
index 97c9780..b887323 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/command/CommandDtoProcessorForActionAbstract.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/processor/CommandDtoProcessorForActionAbstract.java
@@ -16,8 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.isis.applib.services.command;
+package org.apache.isis.applib.services.commanddto.processor;
+import org.apache.isis.applib.services.command.Command;
import org.apache.isis.schema.cmd.v2.ActionDto;
import org.apache.isis.schema.cmd.v2.CommandDto;
import org.apache.isis.schema.cmd.v2.ParamDto;
@@ -27,9 +28,6 @@ import org.apache.isis.schema.cmd.v2.ParamsDto;
* Convenience adapter for command processors for action invocations.
*/
public abstract class CommandDtoProcessorForActionAbstract implements CommandDtoProcessor {
- protected CommandDto asDto(final Command command) {
- return command.getCommandDto();
- }
protected ActionDto getActionDto(final CommandDto commandDto) {
return (ActionDto) commandDto.getMember();
}
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/command/CommandDtoProcessorForPropertyAbstract.java b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/processor/CommandDtoProcessorForPropertyAbstract.java
similarity index 88%
rename from api/applib/src/main/java/org/apache/isis/applib/services/command/CommandDtoProcessorForPropertyAbstract.java
rename to api/applib/src/main/java/org/apache/isis/applib/services/commanddto/processor/CommandDtoProcessorForPropertyAbstract.java
index b8e2dd3..e833809 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/command/CommandDtoProcessorForPropertyAbstract.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/processor/CommandDtoProcessorForPropertyAbstract.java
@@ -16,8 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.isis.applib.services.command;
+package org.apache.isis.applib.services.commanddto.processor;
+import org.apache.isis.applib.services.command.Command;
import org.apache.isis.schema.cmd.v2.CommandDto;
import org.apache.isis.schema.cmd.v2.PropertyDto;
@@ -26,9 +27,6 @@ import org.apache.isis.schema.cmd.v2.PropertyDto;
*/
public abstract class CommandDtoProcessorForPropertyAbstract
implements CommandDtoProcessor {
- protected CommandDto asDto(final Command commandWithDto) {
- return commandWithDto.getCommandDto();
- }
protected PropertyDto getPropertyDto(final CommandDto commandDto) {
return (PropertyDto) commandDto.getMember();
}
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/conmap/command/spi/CommandDtoProcessorService.java b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/processor/spi/CommandDtoProcessorService.java
similarity index 62%
rename from api/applib/src/main/java/org/apache/isis/applib/services/conmap/command/spi/CommandDtoProcessorService.java
rename to api/applib/src/main/java/org/apache/isis/applib/services/commanddto/processor/spi/CommandDtoProcessorService.java
index 48439df..12831f9 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/conmap/command/spi/CommandDtoProcessorService.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/commanddto/processor/spi/CommandDtoProcessorService.java
@@ -16,12 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.isis.applib.services.conmap.command.spi;
+package org.apache.isis.applib.services.commanddto.processor.spi;
-import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.command.CommandDtoProcessor;
-import org.apache.isis.applib.services.conmap.command.ContentMappingServiceForCommandDto;
+import javax.annotation.Nullable;
+
+import org.apache.isis.applib.services.commanddto.processor.CommandDtoProcessor;
+import org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandDto;
import org.apache.isis.schema.cmd.v2.CommandDto;
/**
@@ -32,7 +32,14 @@ import org.apache.isis.schema.cmd.v2.CommandDto;
// tag::refguide[]
public interface CommandDtoProcessorService {
- CommandDto process(final Command command, CommandDto commandDto);
+ /**
+ * @param domainObject - is the target that acts as the source of the
+ * {@link CommandDto}.
+ * @param commandDto - is either <code>null</code>, or is passed from a
+ * previous implementation for further refinement.
+ * @return
+ */
+ CommandDto process(final Object domainObject, @Nullable final CommandDto commandDto);
}
// end::refguide[]
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/conmap/command/ContentMappingServiceForCommandDto.java b/api/applib/src/main/java/org/apache/isis/applib/services/conmap/command/ContentMappingServiceForCommandDto.java
deleted file mode 100644
index c4579c4..0000000
--- a/api/applib/src/main/java/org/apache/isis/applib/services/conmap/command/ContentMappingServiceForCommandDto.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) 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.apache.isis.applib.services.conmap.command;
-
-import java.sql.Timestamp;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.ws.rs.core.MediaType;
-
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.context.annotation.Primary;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Service;
-
-import org.apache.isis.applib.annotation.OrderPrecedence;
-import org.apache.isis.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
-import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.command.CommandDtoProcessor;
-import org.apache.isis.applib.services.conmap.ContentMappingService;
-import org.apache.isis.applib.services.conmap.command.spi.CommandDtoProcessorService;
-import org.apache.isis.applib.services.metamodel.MetaModelService;
-import org.apache.isis.applib.util.schema.CommandDtoUtils;
-import org.apache.isis.core.commons.internal.exceptions._Exceptions;
-import org.apache.isis.schema.cmd.v2.CommandDto;
-import org.apache.isis.schema.common.v2.PeriodDto;
-
-@Service
-@Named("isisApplib.ContentMappingServiceForCommandDto")
-@Order(OrderPrecedence.EARLY)
-@Primary
-@Qualifier("CommandDto")
-public class ContentMappingServiceForCommandDto implements ContentMappingService {
-
- @Override
- public Object map(Object object, final List<MediaType> acceptableMediaTypes) {
- final boolean supported = Util.isSupported(CommandDto.class, acceptableMediaTypes);
- if(!supported) {
- return null;
- }
-
- return asProcessedDto(object);
- }
-
- /**
- * Not part of the {@link ContentMappingService} API.
- */
- public CommandDto map(final Command command) {
- return asProcessedDto(command);
- }
-
- CommandDto asProcessedDto(final Object object) {
- if (!(object instanceof Command)) {
- return null;
- }
- final Command command = (Command) object;
- return asProcessedDto(command);
- }
-
- private CommandDto asProcessedDto(final Command command) {
- if(command == null) {
- return null;
- }
- CommandDto commandDto = command.getCommandDto();
-
- // global processors
- for (final CommandDtoProcessorService commandDtoProcessorService : commandDtoProcessorServices) {
- commandDto = commandDtoProcessorService.process(command, commandDto);
- if(commandDto == null) {
- // any processor could return null, effectively breaking the chain.
- return null;
- }
- }
-
- // specific processors for this specific member (action or property)
- final CommandDtoProcessor commandDtoProcessor =
- metaModelService.commandDtoProcessorFor(commandDto.getMember().getLogicalMemberIdentifier());
- if (commandDtoProcessor == null) {
- return commandDto;
- }
- return commandDtoProcessor.process(command, commandDto);
- }
-
-
- /**
- * Uses the SPI infrastructure to copy over standard properties from {@link Command} to {@link CommandDto}.
- */
- @Service
- @Named("isisApplib.ContentMappingServiceForCommandDto.CopyOverFromCommand")
- // specify quite a high priority since custom processors will probably want to run after this one
- // (but can choose to run before if they wish)
- @Order(OrderPrecedence.EARLY)
- @Qualifier("Command")
- public static class CopyOverFromCommand implements CommandDtoProcessorService {
-
- @Override
- public CommandDto process(final Command command, CommandDto commandDto) {
-
- // for some reason this isn't being persisted initially, so patch it in. TODO: should fix this
- commandDto.setUser(command.getUsername());
-
- // the timestamp field was only introduced in v1.4 of cmd.xsd, so there's no guarantee
- // it will have been populated. We therefore copy the value in from CommandWithDto entity.
- if(commandDto.getTimestamp() == null) {
- final Timestamp timestamp = command.getTimestamp();
- commandDto.setTimestamp(JavaSqlXMLGregorianCalendarMarshalling.toXMLGregorianCalendar(timestamp));
- }
-
- final Bookmark result = command.getResult();
- CommandDtoUtils.setUserData(commandDto,
- UserDataKeys.RESULT, result != null ? result.toString() : null);
- // knowing whether there was an exception is on the master is used to determine whether to
- // continue when replayed on the slave if an exception occurs there also
- Throwable exception = command.getException();
- CommandDtoUtils.setUserData(commandDto,
- UserDataKeys.EXCEPTION,
- _Exceptions.asStacktrace(exception));
-
- PeriodDto timings = CommandDtoUtils.timingsFor(commandDto);
- timings.setStartedAt(JavaSqlXMLGregorianCalendarMarshalling.toXMLGregorianCalendar(command.getStartedAt()));
- timings.setCompletedAt(JavaSqlXMLGregorianCalendarMarshalling.toXMLGregorianCalendar(command.getCompletedAt()));
-
- return commandDto;
- }
- }
-
-
- @Inject
- MetaModelService metaModelService;
-
- @Inject
- List<CommandDtoProcessorService> commandDtoProcessorServices;
-
-}
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelService.java b/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelService.java
index c0c3c09..03dd90d 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelService.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelService.java
@@ -26,7 +26,7 @@ import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties.S
import org.apache.isis.applib.annotation.DomainObject;
import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.command.CommandDtoProcessor;
+import org.apache.isis.applib.services.commanddto.processor.CommandDtoProcessor;
import org.apache.isis.core.commons.internal.collections._Sets;
import org.apache.isis.schema.metamodel.v2.MetamodelDto;
@@ -79,7 +79,7 @@ public interface MetaModelService {
BeanSort sortOf(Bookmark bookmark, Mode mode); // <.>
CommandDtoProcessor commandDtoProcessorFor( // <.>
- String memberIdentifier);
+ String logicalMemberIdentifier);
// end::refguide[]
// tag::refguide-1[]
@@ -92,7 +92,7 @@ public interface MetaModelService {
STRICT,
// end::refguide-1[]
/**
- * If the {@link #sortOf(Class, Mode) sort of} object type is unknown, then return {@link Sort#UNKNOWN}.
+ * If the {@link #sortOf(Class, Mode) sort of} object type is unknown, then return {@link BeanSort#UNKNOWN}.
*/
// tag::refguide-1[]
RELAXED
diff --git a/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java b/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
index ceaf342..e0550c8 100644
--- a/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
+++ b/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
@@ -40,6 +40,7 @@ import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import javax.activation.DataSource;
+import javax.annotation.RegEx;
import javax.inject.Inject;
import javax.inject.Named;
import javax.validation.Constraint;
@@ -3055,62 +3056,57 @@ public class IsisConfiguration {
@Data
public static class CommandReplay {
- private final Primary primary = new Primary();
+ private final PrimaryAccess primaryAccess = new PrimaryAccess();
@Data
- public static class Primary {
- private Optional<String> baseUrl;
- private Optional<String> user;
- private Optional<String> password;
- private Optional<String> baseUrlEndUser;
- private Integer batchSize = 10;
+ public static class PrimaryAccess {
+ @javax.validation.constraints.Pattern(regexp="^http[s]?://[^:]+?(:\\d+)?.*([^/]+/)$")
+ private Optional<String> baseUrlRestful;
+ private Optional<String> user;
+ private Optional<String> password;
+ @javax.validation.constraints.Pattern(regexp="^http[s]?://[^:]+?(:\\d+)?.*([^/]+/)$")
+ private Optional<String> baseUrlWicket;
}
-
- private final Secondary secondary = new Secondary();
+
+ private Integer batchSize = 10;
+
+ private final QuartzSession quartzSession = new QuartzSession();
@Data
- public static class Secondary {
-
- private final QuartzSession quartzSession = new QuartzSession();
- @Data
- public static class QuartzSession {
- /**
- * The user that runs the replay session secondary.
- */
- private String user = "isisModuleExtCommandReplaySecondaryUser";
- private List<String> roles = listOf("isisModuleExtCommandReplaySecondaryRole");
- }
-
- private final QuartzReplicateAndReplayJob quartzReplicateAndReplayJob = new QuartzReplicateAndReplayJob();
+ public static class QuartzSession {
+ /**
+ * The user that runs the replay session secondary.
+ */
+ private String user = "isisModuleExtCommandReplaySecondaryUser";
+ private List<String> roles = listOf("isisModuleExtCommandReplaySecondaryRole");
+ }
+
+ private final QuartzReplicateAndReplayJob quartzReplicateAndReplayJob = new QuartzReplicateAndReplayJob();
+ @Data
+ public static class QuartzReplicateAndReplayJob {
+ /**
+ * Number of milliseconds before starting the job.
+ */
+ private long startDelay = 15000;
+ /**
+ * Number of milliseconds before running again.
+ */
+ private long repeatInterval = 10000;
+ }
+
+ private final Analyser analyser = new Analyser();
+ @Data
+ public static class Analyser {
+ private final Result result = new Result();
@Data
- public static class QuartzReplicateAndReplayJob {
- /**
- * Number of milliseconds before starting the job.
- */
- private long startDelay = 15000;
- /**
- * Number of milliseconds before running again.
- */
- private long repeatInterval = 10000;
+ public static class Result {
+ private boolean enabled = true;
}
-
- private final Analyser analyser = new Analyser();
+ private final Exception exception = new Exception();
@Data
- public static class Analyser {
- private final Result result = new Result();
- @Data
- public static class Result {
- private boolean enabled = true;
- }
- private final Exception exception = new Exception();
- @Data
- public static class Exception {
- private boolean enabled = true;
- }
-
+ public static class Exception {
+ private boolean enabled = true;
}
}
-
-
}
diff --git a/examples/demo/domain/src/main/resources/config/application-secondary.properties b/examples/demo/domain/src/main/resources/config/application-secondary.properties
index 0b1d756..6c2776b 100644
--- a/examples/demo/domain/src/main/resources/config/application-secondary.properties
+++ b/examples/demo/domain/src/main/resources/config/application-secondary.properties
@@ -1,5 +1,6 @@
-isis.extensions.command-replay.primary.base-url=http://localhost:8080
-isis.extensions.command-replay.primary.user=sven
-isis.extensions.command-replay.primary.password=pass
+isis.extensions.command-replay.primary-access.base-url-restful=http://localhost:8080/restful/
+isis.extensions.command-replay.primary-access.base-url-wicket=http://localhost:8080/wicket/
+isis.extensions.command-replay.primary-access.user=sven
+isis.extensions.command-replay.primary-access.password=pass
server.port=9090
\ No newline at end of file
diff --git a/examples/demo/web/pom.xml b/examples/demo/web/pom.xml
index 6108727..83243b3 100644
--- a/examples/demo/web/pom.xml
+++ b/examples/demo/web/pom.xml
@@ -60,7 +60,11 @@
<!-- Extensions -->
<dependency>
<groupId>org.apache.isis.extensions</groupId>
- <artifactId>isis-extensions-command-replay-impl</artifactId>
+ <artifactId>isis-extensions-command-replay-primary</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.isis.extensions</groupId>
+ <artifactId>isis-extensions-command-replay-secondary</artifactId>
</dependency>
</dependencies>
diff --git a/examples/demo/web/src/main/java/demoapp/web/DemoAppManifest.java b/examples/demo/web/src/main/java/demoapp/web/DemoAppManifest.java
index d79a04e..0ec690e 100644
--- a/examples/demo/web/src/main/java/demoapp/web/DemoAppManifest.java
+++ b/examples/demo/web/src/main/java/demoapp/web/DemoAppManifest.java
@@ -26,10 +26,9 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
-import org.apache.isis.extensions.commandreplay.impl.IsisModuleExtCommandReplayImpl;
+import org.apache.isis.extensions.commandreplay.primary.IsisModuleExtCommandReplayPrimary;
+import org.apache.isis.extensions.commandreplay.secondary.IsisModuleExtCommandReplaySecondary;
import org.apache.isis.extensions.cors.impl.IsisModuleExtCorsImpl;
-import org.apache.isis.extensions.quartz.IsisModuleExtQuartzImpl;
import org.apache.isis.extensions.secman.encryption.jbcrypt.IsisModuleExtSecmanEncryptionJbcrypt;
import org.apache.isis.extensions.secman.jdo.IsisModuleExtSecmanPersistenceJdo;
import org.apache.isis.extensions.secman.model.IsisModuleExtSecmanModel;
@@ -55,7 +54,8 @@ import demoapp.dom._infra.fixtures.DemoFixtureScript;
DemoModule.class, // shared demo core module
// commands
- IsisModuleExtCommandReplayImpl.class,
+ IsisModuleExtCommandReplayPrimary.class,
+ IsisModuleExtCommandReplaySecondary.class,
// SECURITY
IsisModuleSecurityShiro.class,
diff --git a/examples/demo/wicket/src/main/resources/log4j2-spring.xml b/examples/demo/wicket/src/main/resources/log4j2-spring.xml
index 5d9f666..4cdedf1 100644
--- a/examples/demo/wicket/src/main/resources/log4j2-spring.xml
+++ b/examples/demo/wicket/src/main/resources/log4j2-spring.xml
@@ -56,7 +56,7 @@ under the License.
<!-- debugging -->
<Logger name="org.apache.isis.applib.services.command.CommandServiceDefault" level="warn" />
- <Logger name="org.apache.isis.extensions.commandreplay.impl.job.callables.ReplicateAndRunCommands" level="debug" />
+ <Logger name="org.apache.isis.extensions.commandreplay.secondary.jobcallables.ReplicateAndRunCommands" level="debug" />
<Root level="info">
<AppenderRef ref="Console" />
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java
index 1ba4381..248a56b 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java
@@ -45,7 +45,8 @@ import org.apache.isis.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
import org.apache.isis.applib.services.DomainChangeRecord;
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.conmap.command.UserDataKeys;
+import org.apache.isis.applib.services.commanddto.HasCommandDto;
+import org.apache.isis.applib.services.commanddto.conmap.UserDataKeys;
import org.apache.isis.applib.services.tablecol.TableColumnOrderForCollectionTypeAbstract;
import org.apache.isis.applib.types.MemberIdentifierType;
import org.apache.isis.applib.util.ObjectContracts;
@@ -186,11 +187,11 @@ import lombok.extern.log4j.Log4j2;
+ " && startedAt != null "
+ " && completedAt != null "
+ "ORDER BY this.timestamp ASC"),
- // most recent replayed command previously replicated from primary to
+ // most recent (replayable) command previously replicated from primary to
// secondary. This should always exist except for the very first times
// (after restored the prod DB to secondary).
@javax.jdo.annotations.Query(
- name="findReplayedHwm",
+ name="findReplicatedHwm",
value="SELECT "
+ "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
+ "WHERE (replayState == 'OK' || replayState == 'FAILED') "
@@ -251,7 +252,7 @@ import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
public class CommandJdo
- implements DomainChangeRecord, Comparable<CommandJdo> {
+ implements DomainChangeRecord, Comparable<CommandJdo>, HasCommandDto {
public static class TitleUiEvent extends IsisModuleExtCommandLogImpl.TitleUiEvent<CommandJdo> { }
public static class IconUiEvent extends IsisModuleExtCommandLogImpl.IconUiEvent<CommandJdo> { }
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdoRepository.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdoRepository.java
index 1f632a7..926335f 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdoRepository.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdoRepository.java
@@ -230,7 +230,7 @@ public class CommandJdoRepository {
* the primary.
*
* @param uniqueId - the identifier of the {@link CommandJdo command} being
- * the replay hwm (using {@link #findReplayedHwm()} on the
+ * the replay hwm (using {@link #findReplicatedHwm()} on the
* secondary), or null if no HWM was found there.
* @param batchSize - to restrict the number returned (so that replay
* commands can be batched).
@@ -301,12 +301,12 @@ public class CommandJdoRepository {
* production database was restored to the secondary
* </p>
*/
- public CommandJdo findReplayedHwm() {
+ public CommandJdo findReplicatedHwm() {
// most recent replayable command, replicated from primary to secondary
return repositoryService.firstMatch(
new QueryDefault<>(
- CommandJdo.class, "findReplayedHwm"))
+ CommandJdo.class, "findReplicatedHwm"))
.orElseGet(() -> {
// otherwise, the most recent completed command, run on the secondary,
// this corresponds to a command restored from a copy of
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/fetch/PrimaryConfig.java b/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/fetch/PrimaryConfig.java
deleted file mode 100644
index 81fb315..0000000
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/fetch/PrimaryConfig.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.apache.isis.extensions.commandreplay.impl.fetch;
-
-import javax.validation.constraints.NotNull;
-
-import org.springframework.stereotype.Service;
-
-import org.apache.isis.core.config.IsisConfiguration;
-
-import lombok.Getter;
-import lombok.val;
-import lombok.extern.log4j.Log4j2;
-
-@Service
-@Log4j2
-public class PrimaryConfig {
-
- @Getter final String user;
- @Getter final String password;
- @Getter final String baseUrl;
- @Getter final int batchSize;
-
- public PrimaryConfig(@NotNull final IsisConfiguration isisConfiguration) {
- val config = isisConfiguration.getExtensions().getCommandReplay().getPrimary();
- user = config.getUser().orElse(null);
- password = config.getPassword().orElse(null);
- baseUrl = config.getBaseUrl()
- .map(x -> !x.endsWith("/") ? x + "/" : x)
- .orElse(null);
- batchSize = config.getBatchSize();
- }
-
-
- public boolean isConfigured() {
- return user != null &&
- password != null &&
- baseUrl != null;
- }
-}
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/fetch/SecondaryConfig.java b/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/fetch/SecondaryConfig.java
deleted file mode 100644
index 4680303..0000000
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/fetch/SecondaryConfig.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.apache.isis.extensions.commandreplay.impl.fetch;
-
-import java.util.List;
-
-import javax.validation.constraints.NotNull;
-
-import org.springframework.stereotype.Service;
-
-import org.apache.isis.core.config.IsisConfiguration;
-
-import lombok.Getter;
-import lombok.val;
-import lombok.extern.log4j.Log4j2;
-
-@Service
-@Log4j2
-public class SecondaryConfig {
-
- @Getter final String user;
- @Getter final List<String> roles;
-
- public SecondaryConfig(@NotNull final IsisConfiguration isisConfiguration) {
- val config = isisConfiguration.getExtensions().getCommandReplay().getSecondary();
- user = config.getQuartzSession().getUser();
- roles = config.getQuartzSession().getRoles();
- }
-
- public boolean isConfigured() {
- return user != null &&
- roles != null;
- }
-}
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_openOnPrimary.java b/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_openOnPrimary.java
deleted file mode 100644
index c5af120..0000000
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_openOnPrimary.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.apache.isis.extensions.commandreplay.impl.mixins;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import javax.inject.Inject;
-
-import org.apache.isis.applib.ApplicationException;
-import org.apache.isis.applib.annotation.Action;
-import org.apache.isis.applib.annotation.MemberOrder;
-import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.applib.services.bookmark.BookmarkService;
-import org.apache.isis.core.config.IsisConfiguration;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandreplay.impl.IsisModuleExtCommandReplayImpl;
-
-@Action(
- semantics = SemanticsOf.SAFE,
- domainEvent = CommandJdo_openOnPrimary.ActionDomainEvent.class
-)
-public class CommandJdo_openOnPrimary<T> {
-
- public static class ActionDomainEvent
- extends IsisModuleExtCommandReplayImpl.ActionDomainEvent<CommandJdo_openOnPrimary> { }
-
- private final CommandJdo commandJdo;
- public CommandJdo_openOnPrimary(CommandJdo commandJdo) {
- this.commandJdo = commandJdo;
- }
-
- @MemberOrder(name = "transactionId", sequence = "1")
- public URL act() {
- final String baseUrlPrefix = lookupBaseUrlPrefix();
- final String urlSuffix = bookmarkService2.bookmarkFor(commandJdo).toString();
-
- try {
- return new URL(baseUrlPrefix + urlSuffix);
- } catch (MalformedURLException e) {
- throw new ApplicationException(e);
- }
- }
-
- public boolean hideAct() {
- return lookupBaseUrlPrefix() == null;
- }
-
- private String lookupBaseUrlPrefix() {
- return isisConfiguration.getExtensions().getCommandReplay().getPrimary().getBaseUrlEndUser()
- .map(x -> !x.endsWith("/") ? x + "/" : x)
- .map(x -> x + "wicket/entity/")
- .orElse(null);
- }
-
- @Inject IsisConfiguration isisConfiguration;
- @Inject BookmarkService bookmarkService2;
-
-}
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_replayQueue.java b/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_replayQueue.java
deleted file mode 100644
index f4b20b3..0000000
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_replayQueue.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.apache.isis.extensions.commandreplay.impl.mixins;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.isis.applib.annotation.Collection;
-import org.apache.isis.applib.annotation.CollectionLayout;
-import org.apache.isis.applib.annotation.MemberOrder;
-import org.apache.isis.applib.annotation.Mixin;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
-import org.apache.isis.extensions.commandreplay.impl.IsisModuleExtCommandReplayImpl;
-import org.apache.isis.extensions.commandreplay.impl.fetch.PrimaryConfig;
-
-@Collection(
- domainEvent = CommandJdo_replayQueue.CollectionDomainEvent.class
-)
-@CollectionLayout(
- defaultView = "table"
-)
-@Mixin(method = "coll")
-public class CommandJdo_replayQueue {
-
- public static class CollectionDomainEvent
- extends IsisModuleExtCommandReplayImpl.CollectionDomainEvent<CommandJdo_replayQueue, CommandJdo> { }
-
- private final CommandJdo commandJdo;
- public CommandJdo_replayQueue(final CommandJdo commandJdo) {
- this.commandJdo = commandJdo;
- }
-
- @MemberOrder(sequence = "100.100")
- public List<CommandJdo> coll() {
- return commandJdoRepository.findReplayedOnSecondary();
- }
-
- public boolean hideColl() {
- return !primaryConfig.isConfigured();
- }
-
- @Inject
- PrimaryConfig primaryConfig;
- @Inject
- CommandJdoRepository commandJdoRepository;
-
-}
diff --git a/extensions/core/command-replay/pom.xml b/extensions/core/command-replay/pom.xml
index 208215a..8bbfddf 100644
--- a/extensions/core/command-replay/pom.xml
+++ b/extensions/core/command-replay/pom.xml
@@ -56,7 +56,8 @@
</dependencyManagement>
<modules>
- <module>impl</module>
+ <module>primary</module>
+ <module>secondary</module>
</modules>
</project>
diff --git a/extensions/core/command-replay/impl/pom.xml b/extensions/core/command-replay/primary/pom.xml
similarity index 83%
copy from extensions/core/command-replay/impl/pom.xml
copy to extensions/core/command-replay/primary/pom.xml
index 195e92b..45892f0 100644
--- a/extensions/core/command-replay/impl/pom.xml
+++ b/extensions/core/command-replay/primary/pom.xml
@@ -19,19 +19,18 @@
<version>2.0.0-SNAPSHOT</version>
</parent>
- <artifactId>isis-extensions-command-replay-impl</artifactId>
- <name>Apache Isis Ext - Command Replay Implementation</name>
+ <artifactId>isis-extensions-command-replay-primary</artifactId>
+ <name>Apache Isis Ext - Command Replay for Primary</name>
<packaging>jar</packaging>
<description>
- A module providing a Quartz Job to run on a secondary system,
- for obtaining commands from a primary and saving them so that they are replayed.
+ A module for obtaining commands from a primary
</description>
<properties>
- <jar-plugin.automaticModuleName>org.apache.isis.extensions.commandreplay.impl</jar-plugin.automaticModuleName>
- <git-plugin.propertiesDir>org/apache/isis/extensions/commandreplay</git-plugin.propertiesDir>
+ <jar-plugin.automaticModuleName>org.apache.isis.extensions.commandreplay.primary</jar-plugin.automaticModuleName>
+ <git-plugin.propertiesDir>org/apache/isis/extensions/commandreplay/primary</git-plugin.propertiesDir>
</properties>
<dependencies>
@@ -70,11 +69,6 @@
<artifactId>isis-extensions-command-log-impl</artifactId>
</dependency>
- <dependency>
- <groupId>org.apache.isis.extensions</groupId>
- <artifactId>isis-extensions-quartz-impl</artifactId>
- </dependency>
-
</dependencies>
</project>
diff --git a/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/IsisModuleExtCommandReplayPrimary.java b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/IsisModuleExtCommandReplayPrimary.java
new file mode 100644
index 0000000..5086b15
--- /dev/null
+++ b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/IsisModuleExtCommandReplayPrimary.java
@@ -0,0 +1,33 @@
+package org.apache.isis.extensions.commandreplay.primary;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.Profile;
+
+import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
+import org.apache.isis.extensions.commandreplay.primary.spiimpl.CaptureResultOfCommand;
+import org.apache.isis.extensions.commandreplay.primary.ui.CommandReplayOnPrimaryService;
+
+@Configuration
+@Import({
+ // @Configuration's
+ IsisModuleExtCommandLogImpl.class,
+
+ // @Service's
+ CommandReplayOnPrimaryService.class,
+ CaptureResultOfCommand.class,
+
+})
+@Profile("primary")
+public class IsisModuleExtCommandReplayPrimary {
+
+ public abstract static class ActionDomainEvent<S>
+ extends org.apache.isis.applib.events.domain.ActionDomainEvent<S> { }
+
+ public abstract static class CollectionDomainEvent<S,T>
+ extends org.apache.isis.applib.events.domain.CollectionDomainEvent<S,T> { }
+
+ public abstract static class PropertyDomainEvent<S,T>
+ extends org.apache.isis.applib.events.domain.PropertyDomainEvent<S,T> { }
+
+}
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_download.java b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/mixins/CommandJdo_download.java
similarity index 61%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_download.java
rename to extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/mixins/CommandJdo_download.java
index 766e6ac..82848f5 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_download.java
+++ b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/mixins/CommandJdo_download.java
@@ -1,4 +1,4 @@
-package org.apache.isis.extensions.commandreplay.impl.mixins;
+package org.apache.isis.extensions.commandreplay.primary.mixins;
import javax.inject.Inject;
@@ -9,29 +9,27 @@ import org.apache.isis.applib.annotation.ParameterLayout;
import org.apache.isis.applib.annotation.SemanticsOf;
import org.apache.isis.applib.value.Clob;
import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandreplay.impl.IsisModuleExtCommandReplayImpl;
+import org.apache.isis.extensions.commandreplay.primary.IsisModuleExtCommandReplayPrimary;
+import org.apache.isis.extensions.commandreplay.primary.ui.CommandReplayOnPrimaryService;
-import org.apache.isis.extensions.commandreplay.impl.ui.CommandReplayOnPrimaryService;
-@Action(
- semantics = SemanticsOf.NON_IDEMPOTENT,
- domainEvent = CommandJdo_download.ActionDomainEvent.class
+import lombok.RequiredArgsConstructor;
+@Action(
+ semantics = SemanticsOf.NON_IDEMPOTENT,
+ domainEvent = CommandJdo_download.ActionDomainEvent.class
)
@ActionLayout(
- cssClassFa = "fa-download",
- position = ActionLayout.Position.PANEL
+ cssClassFa = "fa-download",
+ position = ActionLayout.Position.PANEL
)
+@RequiredArgsConstructor
public class CommandJdo_download {
public static class ActionDomainEvent
- extends IsisModuleExtCommandReplayImpl.ActionDomainEvent<CommandJdo_download> { }
+ extends IsisModuleExtCommandReplayPrimary.ActionDomainEvent<CommandJdo_download> { }
private final CommandJdo commandJdo;
- public CommandJdo_download(CommandJdo commandJdo) {
- this.commandJdo = commandJdo;
- }
-
@MemberOrder(name = "arguments", sequence = "1")
public Clob act(
@@ -43,7 +41,8 @@ public class CommandJdo_download {
return "command";
}
-
@Inject
CommandReplayOnPrimaryService commandReplayOnPrimaryService;
+
+
}
diff --git a/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/spiimpl/CaptureResultOfCommand.java b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/spiimpl/CaptureResultOfCommand.java
new file mode 100644
index 0000000..0328e29
--- /dev/null
+++ b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/spiimpl/CaptureResultOfCommand.java
@@ -0,0 +1,62 @@
+package org.apache.isis.extensions.commandreplay.primary.spiimpl;
+
+import javax.inject.Named;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
+
+import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.commanddto.conmap.UserDataKeys;
+import org.apache.isis.applib.services.commanddto.processor.spi.CommandDtoProcessorService;
+import org.apache.isis.applib.util.schema.CommandDtoUtils;
+import org.apache.isis.core.commons.internal.exceptions._Exceptions;
+import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
+import org.apache.isis.schema.cmd.v2.CommandDto;
+import org.apache.isis.schema.common.v2.PeriodDto;
+
+import lombok.val;
+
+/**
+ * Uses the SPI infrastructure to copy over standard properties from {@link Command} to {@link CommandDto}.
+ */
+@Service
+@Named("isisExtensionsCommandReplayPrimary.CaptureResultOfCommand")
+// specify quite a high priority since custom processors will probably want to run after this one
+// (but can choose to run before if they wish)
+@Order(OrderPrecedence.EARLY)
+public class CaptureResultOfCommand implements CommandDtoProcessorService {
+
+ @Override
+ public CommandDto process(final Object domainObject, CommandDto commandDto) {
+
+ if (!(domainObject instanceof CommandJdo)) {
+ return commandDto;
+ }
+
+ val commandJdo = (CommandJdo) domainObject;
+ if(commandDto == null) {
+ commandDto = commandJdo.getCommandDto();
+ }
+
+ final Bookmark result = commandJdo.getResult();
+ CommandDtoUtils.setUserData(commandDto,
+ UserDataKeys.RESULT, result != null ? result.toString() : null);
+
+ // knowing whether there was an exception is on the primary is
+ // used to determine whether to continue when replayed on the
+ // secondary if an exception occurs there also
+ CommandDtoUtils.setUserData(commandDto,
+ UserDataKeys.EXCEPTION,
+ commandJdo.getException());
+
+ val timings = CommandDtoUtils.timingsFor(commandDto);
+ timings.setStartedAt(JavaSqlXMLGregorianCalendarMarshalling.toXMLGregorianCalendar(commandJdo.getStartedAt()));
+ timings.setCompletedAt(JavaSqlXMLGregorianCalendarMarshalling.toXMLGregorianCalendar(commandJdo.getCompletedAt()));
+
+ return commandDto;
+ }
+}
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/ui/CommandReplayOnPrimaryService.java b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/ui/CommandReplayOnPrimaryService.java
similarity index 82%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/ui/CommandReplayOnPrimaryService.java
rename to extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/ui/CommandReplayOnPrimaryService.java
index f0570e0..1cc08f5 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/ui/CommandReplayOnPrimaryService.java
+++ b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/ui/CommandReplayOnPrimaryService.java
@@ -1,10 +1,13 @@
-package org.apache.isis.extensions.commandreplay.impl.ui;
+package org.apache.isis.extensions.commandreplay.primary.ui;
import java.util.List;
import java.util.UUID;
import javax.annotation.Nullable;
import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.springframework.core.annotation.Order;
import org.apache.isis.applib.ApplicationException;
import org.apache.isis.applib.annotation.Action;
@@ -13,15 +16,18 @@ import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.DomainServiceLayout;
import org.apache.isis.applib.annotation.MemberOrder;
import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.applib.annotation.Parameter;
import org.apache.isis.applib.annotation.ParameterLayout;
import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.applib.services.conmap.command.ContentMappingServiceForCommandsDto;
+import org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandsDto;
import org.apache.isis.applib.services.jaxb.JaxbService;
import org.apache.isis.applib.services.message.MessageService;
import org.apache.isis.applib.value.Clob;
import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
-import org.apache.isis.extensions.commandreplay.impl.IsisModuleExtCommandReplayImpl;
+import org.apache.isis.extensions.commandreplay.primary.IsisModuleExtCommandReplayPrimary;
import org.apache.isis.schema.cmd.v2.CommandDto;
import org.apache.isis.schema.cmd.v2.CommandsDto;
@@ -29,18 +35,20 @@ import lombok.Getter;
import lombok.extern.log4j.Log4j2;
@DomainService(
- nature = NatureOfService.VIEW,
- objectType = "isisExtensionsCommandReplay.CommandReplayOnPrimaryService"
+ nature = NatureOfService.VIEW,
+ objectType = "isisExtensionsCommandReplayPrimary.CommandReplayOnPrimaryService"
)
@DomainServiceLayout(
- named = "Activity",
- menuBar = DomainServiceLayout.MenuBar.SECONDARY
+ named = "Activity",
+ menuBar = DomainServiceLayout.MenuBar.SECONDARY
)
+@Named("isisExtensionsCommandReplayPrimary.CommandReplayOnPrimaryService")
+@Order(OrderPrecedence.MIDPOINT)
@Log4j2
public class CommandReplayOnPrimaryService {
public static abstract class ActionDomainEvent
- extends IsisModuleExtCommandReplayImpl.ActionDomainEvent<CommandReplayOnPrimaryService> { }
+ extends IsisModuleExtCommandReplayPrimary.ActionDomainEvent<CommandReplayOnPrimaryService> { }
public static class FindCommandsOnPrimarySinceDomainEvent extends ActionDomainEvent { }
@@ -58,7 +66,7 @@ public class CommandReplayOnPrimaryService {
* These actions should be called with HTTP Accept Header set to:
* <code>application/xml;profile="urn:org.restfulobjects:repr-types/action-result";x-ro-domain-type="org.apache.isis.schema.cmd.v1.CommandsDto"</code>
*
- * @param transactionId - to search from. This transactionId will <i>not</i> be included in the response.
+ * @param uniqueId - to search from. This transactionId will <i>not</i> be included in the response.
* @param batchSize - the maximum number of commands to return. If not specified, all found will be returned.
*
* @return
@@ -68,16 +76,16 @@ public class CommandReplayOnPrimaryService {
@ActionLayout(cssClassFa = "fa-files-o")
@MemberOrder(sequence="40")
public List<CommandJdo> findCommandsOnPrimarySince(
- @Nullable
- @ParameterLayout(named="Transaction Id")
- final UUID transactionId,
- @Nullable
+ @Parameter(optionality = Optionality.OPTIONAL) // @Nullable
+ @ParameterLayout(named="Unique Id")
+ final UUID uniqueId,
+ @Parameter(optionality = Optionality.OPTIONAL) // @Nullable
@ParameterLayout(named="Batch size")
final Integer batchSize)
throws NotFoundException {
- final List<CommandJdo> commands = commandServiceRepository.findSince(transactionId, batchSize);
+ final List<CommandJdo> commands = commandServiceRepository.findSince(uniqueId, batchSize);
if(commands == null) {
- throw new NotFoundException(transactionId);
+ throw new NotFoundException(uniqueId);
}
return commands;
}
@@ -172,6 +180,7 @@ public class CommandReplayOnPrimaryService {
return uuid != null ? uuid.toString() : "00000000-0000-0000-0000-000000000000";
}
+
@Inject CommandJdoRepository commandServiceRepository;
@Inject JaxbService jaxbService;
@Inject MessageService messageService;
diff --git a/extensions/core/command-replay/impl/pom.xml b/extensions/core/command-replay/secondary/pom.xml
similarity index 92%
rename from extensions/core/command-replay/impl/pom.xml
rename to extensions/core/command-replay/secondary/pom.xml
index 195e92b..9e0e49e 100644
--- a/extensions/core/command-replay/impl/pom.xml
+++ b/extensions/core/command-replay/secondary/pom.xml
@@ -19,8 +19,8 @@
<version>2.0.0-SNAPSHOT</version>
</parent>
- <artifactId>isis-extensions-command-replay-impl</artifactId>
- <name>Apache Isis Ext - Command Replay Implementation</name>
+ <artifactId>isis-extensions-command-replay-secondary</artifactId>
+ <name>Apache Isis Ext - Command Replay for Secondary</name>
<packaging>jar</packaging>
@@ -30,8 +30,8 @@
</description>
<properties>
- <jar-plugin.automaticModuleName>org.apache.isis.extensions.commandreplay.impl</jar-plugin.automaticModuleName>
- <git-plugin.propertiesDir>org/apache/isis/extensions/commandreplay</git-plugin.propertiesDir>
+ <jar-plugin.automaticModuleName>org.apache.isis.extensions.commandreplay.secondary</jar-plugin.automaticModuleName>
+ <git-plugin.propertiesDir>org/apache/isis/extensions/commandreplay/secondary</git-plugin.propertiesDir>
</properties>
<dependencies>
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/IsisModuleExtCommandReplayImpl.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/IsisModuleExtCommandReplaySecondary.java
similarity index 77%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/IsisModuleExtCommandReplayImpl.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/IsisModuleExtCommandReplaySecondary.java
index a7d27ff..c7e115c 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/IsisModuleExtCommandReplayImpl.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/IsisModuleExtCommandReplaySecondary.java
@@ -1,4 +1,4 @@
-package org.apache.isis.extensions.commandreplay.impl;
+package org.apache.isis.extensions.commandreplay.secondary;
import javax.inject.Inject;
@@ -21,17 +21,15 @@ import org.springframework.scheduling.quartz.SpringBeanJobFactory;
import org.apache.isis.core.config.IsisConfiguration;
import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
-import org.apache.isis.extensions.commandreplay.impl.analysis.CommandReplayAnalyserException;
-import org.apache.isis.extensions.commandreplay.impl.analysis.CommandReplayAnalyserResult;
-import org.apache.isis.extensions.commandreplay.impl.executor.CommandExecutorServiceWithTime;
-import org.apache.isis.extensions.commandreplay.impl.fetch.CommandFetcher;
-import org.apache.isis.extensions.commandreplay.impl.fetch.PrimaryConfig;
-import org.apache.isis.extensions.commandreplay.impl.clock.TickingClockService;
-import org.apache.isis.extensions.commandreplay.impl.analysis.CommandReplayAnalysisService;
-import org.apache.isis.extensions.commandreplay.impl.fetch.SecondaryConfig;
-import org.apache.isis.extensions.commandreplay.impl.job.ReplicateAndReplayJob;
-import org.apache.isis.extensions.commandreplay.impl.ui.CommandReplayOnPrimaryService;
-import org.apache.isis.extensions.commandreplay.impl.ui.CommandReplayOnSecondaryService;
+import org.apache.isis.extensions.commandreplay.secondary.analyser.CommandReplayAnalyserException;
+import org.apache.isis.extensions.commandreplay.secondary.analyser.CommandReplayAnalyserResult;
+import org.apache.isis.extensions.commandreplay.secondary.analysis.CommandReplayAnalysisService;
+import org.apache.isis.extensions.commandreplay.secondary.clock.TickingClockService;
+import org.apache.isis.extensions.commandreplay.secondary.executor.CommandExecutorServiceWithTime;
+import org.apache.isis.extensions.commandreplay.secondary.fetch.CommandFetcher;
+import org.apache.isis.extensions.commandreplay.secondary.config.SecondaryConfig;
+import org.apache.isis.extensions.commandreplay.secondary.job.ReplicateAndReplayJob;
+import org.apache.isis.extensions.commandreplay.secondary.ui.CommandReplayOnSecondaryService;
import org.apache.isis.extensions.quartz.IsisModuleExtQuartzImpl;
import org.apache.isis.extensions.quartz.spring.AutowiringSpringBeanJobFactory;
@@ -43,26 +41,23 @@ import lombok.val;
IsisModuleExtCommandLogImpl.class,
IsisModuleExtQuartzImpl.class,
- // @DomainService's
+ // @Service's
CommandExecutorServiceWithTime.class,
CommandFetcher.class,
CommandReplayAnalyserResult.class,
CommandReplayAnalyserException.class,
CommandReplayAnalysisService.class,
- CommandReplayOnPrimaryService.class,
CommandReplayOnSecondaryService.class,
TickingClockService.class,
// @Service's
- PrimaryConfig.class,
SecondaryConfig.class,
-
})
@Profile("secondary")
-public class IsisModuleExtCommandReplayImpl {
+public class IsisModuleExtCommandReplaySecondary {
public abstract static class ActionDomainEvent<S>
- extends org.apache.isis.applib.events.domain.ActionDomainEvent<S> { }
+ extends org.apache.isis.applib.events.domain.ActionDomainEvent<S> { }
public abstract static class CollectionDomainEvent<S,T>
extends org.apache.isis.applib.events.domain.CollectionDomainEvent<S,T> { }
@@ -70,7 +65,6 @@ public class IsisModuleExtCommandReplayImpl {
public abstract static class PropertyDomainEvent<S,T>
extends org.apache.isis.applib.events.domain.PropertyDomainEvent<S,T> { }
-
@Inject ApplicationContext applicationContext;
@Inject IsisConfiguration isisConfiguration;
@@ -87,7 +81,7 @@ public class IsisModuleExtCommandReplayImpl {
public SimpleTriggerFactoryBean replicateAndReplayTriggerFactory(@Qualifier("ReplicateAndReplayJob") JobDetail job) {
val triggerFactory = new SimpleTriggerFactoryBean();
triggerFactory.setJobDetail(job);
- val config = isisConfiguration.getExtensions().getCommandReplay().getSecondary().getQuartzReplicateAndReplayJob();
+ val config = isisConfiguration.getExtensions().getCommandReplay().getQuartzReplicateAndReplayJob();
triggerFactory.setRepeatInterval(config.getRepeatInterval());
triggerFactory.setStartDelay(config.getStartDelay());
triggerFactory.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/SecondaryStatus.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/SecondaryStatus.java
similarity index 76%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/SecondaryStatus.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/SecondaryStatus.java
index 1cc6c96..00eeb13 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/SecondaryStatus.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/SecondaryStatus.java
@@ -1,4 +1,4 @@
-package org.apache.isis.extensions.commandreplay.impl;
+package org.apache.isis.extensions.commandreplay.secondary;
public enum SecondaryStatus {
TICKING_CLOCK_STATUS_UNKNOWN,
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/StatusException.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/StatusException.java
similarity index 85%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/StatusException.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/StatusException.java
index 6ba46e6..1746e68 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/StatusException.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/StatusException.java
@@ -1,4 +1,4 @@
-package org.apache.isis.extensions.commandreplay.impl;
+package org.apache.isis.extensions.commandreplay.secondary;
public class StatusException extends Exception {
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/analysis/CommandReplayAnalyser.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyser.java
similarity index 82%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/analysis/CommandReplayAnalyser.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyser.java
index e4d3e50..3e06c2a 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/analysis/CommandReplayAnalyser.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyser.java
@@ -1,4 +1,4 @@
-package org.apache.isis.extensions.commandreplay.impl.analysis;
+package org.apache.isis.extensions.commandreplay.secondary.analyser;
import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/analysis/CommandReplayAnalyserException.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyserException.java
similarity index 79%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/analysis/CommandReplayAnalyserException.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyserException.java
index 5039a11..95147dd 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/analysis/CommandReplayAnalyserException.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyserException.java
@@ -1,20 +1,25 @@
-package org.apache.isis.extensions.commandreplay.impl.analysis;
+package org.apache.isis.extensions.commandreplay.secondary.analyser;
import javax.annotation.PostConstruct;
+import javax.inject.Named;
import com.google.common.base.Objects;
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.services.conmap.command.UserDataKeys;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
+
+import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.applib.services.commanddto.conmap.UserDataKeys;
import org.apache.isis.applib.util.schema.CommandDtoUtils;
import org.apache.isis.core.config.IsisConfiguration;
import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.schema.cmd.v2.CommandDto;
import lombok.RequiredArgsConstructor;
import lombok.val;
-@DomainService()
+@Service
+@Named("isisExtensionsCommandReplaySecondary.CommandReplayAnalyserException")
+@Order(OrderPrecedence.MIDPOINT)
@RequiredArgsConstructor
public class CommandReplayAnalyserException implements CommandReplayAnalyser {
@@ -23,7 +28,7 @@ public class CommandReplayAnalyserException implements CommandReplayAnalyser {
@PostConstruct
public void init() {
- enabled = isisConfiguration.getExtensions().getCommandReplay().getSecondary().getAnalyser().getResult().isEnabled();
+ enabled = isisConfiguration.getExtensions().getCommandReplay().getAnalyser().getResult().isEnabled();
}
@Override
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/analysis/CommandReplayAnalyserResult.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyserResult.java
similarity index 75%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/analysis/CommandReplayAnalyserResult.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyserResult.java
index 3db2db2..dc1012d 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/analysis/CommandReplayAnalyserResult.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyserResult.java
@@ -1,12 +1,15 @@
-package org.apache.isis.extensions.commandreplay.impl.analysis;
+package org.apache.isis.extensions.commandreplay.secondary.analyser;
import javax.annotation.PostConstruct;
+import javax.inject.Named;
import com.google.common.base.Objects;
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.conmap.command.UserDataKeys;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
+
+import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.applib.services.commanddto.conmap.UserDataKeys;
import org.apache.isis.applib.util.schema.CommandDtoUtils;
import org.apache.isis.core.config.IsisConfiguration;
@@ -16,7 +19,9 @@ import org.apache.isis.schema.cmd.v2.CommandDto;
import lombok.RequiredArgsConstructor;
import lombok.val;
-@DomainService()
+@Service
+@Named("isisExtensionsCommandReplaySecondary.CommandReplayAnalyserResult")
+@Order(OrderPrecedence.MIDPOINT)
@RequiredArgsConstructor
public class CommandReplayAnalyserResult implements CommandReplayAnalyser {
@@ -25,7 +30,7 @@ public class CommandReplayAnalyserResult implements CommandReplayAnalyser {
@PostConstruct
public void init() {
- enabled = isisConfiguration.getExtensions().getCommandReplay().getSecondary().getAnalyser().getException().isEnabled();
+ enabled = isisConfiguration.getExtensions().getCommandReplay().getAnalyser().getException().isEnabled();
}
@Override
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/analysis/CommandReplayAnalysisService.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analysis/CommandReplayAnalysisService.java
similarity index 74%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/analysis/CommandReplayAnalysisService.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analysis/CommandReplayAnalysisService.java
index dc2e223..fa2d864 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/analysis/CommandReplayAnalysisService.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analysis/CommandReplayAnalysisService.java
@@ -1,15 +1,23 @@
-package org.apache.isis.extensions.commandreplay.impl.analysis;
+package org.apache.isis.extensions.commandreplay.secondary.analysis;
import java.util.List;
import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.OrderPrecedence;
import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
+import org.apache.isis.extensions.commandreplay.secondary.analyser.CommandReplayAnalyser;
import lombok.extern.log4j.Log4j2;
-@DomainService()
+@Service
+@Named("isisExtensionsCommandReplaySecondary.CommandReplayAnalysisService")
+@Order(OrderPrecedence.MIDPOINT)
@Log4j2
public class CommandReplayAnalysisService {
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/clock/TickingClockService.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/clock/TickingClockService.java
similarity index 78%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/clock/TickingClockService.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/clock/TickingClockService.java
index 0f7a798..bee85da 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/clock/TickingClockService.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/clock/TickingClockService.java
@@ -1,20 +1,20 @@
-package org.apache.isis.extensions.commandreplay.impl.clock;
+package org.apache.isis.extensions.commandreplay.secondary.clock;
import java.sql.Timestamp;
-import java.util.Optional;
import java.util.function.Supplier;
import javax.annotation.PostConstruct;
-import javax.inject.Inject;
+import javax.inject.Named;
-import org.springframework.context.annotation.Profile;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.annotation.OrderPrecedence;
import org.apache.isis.applib.clock.Clock;
import org.apache.isis.core.config.IsisConfiguration;
import org.apache.isis.testing.fixtures.applib.clock.TickingFixtureClock;
+import lombok.RequiredArgsConstructor;
import lombok.val;
import lombok.extern.log4j.Log4j2;
@@ -35,22 +35,25 @@ import lombok.extern.log4j.Log4j2;
* systems, eg a replay secondary.
* </p>
*/
-@DomainService()
+@Service()
+@Named("isisExtensionsCommandReplaySecondary.TickingClockService")
+@Order(OrderPrecedence.MIDPOINT)
@Log4j2
+@RequiredArgsConstructor
public class TickingClockService {
- @Inject IsisConfiguration isisConfiguration;
+ final IsisConfiguration isisConfiguration;
@PostConstruct
public void init() {
- val baseUrl = isisConfiguration.getExtensions().getCommandReplay().getPrimary().getBaseUrl();
- val user = isisConfiguration.getExtensions().getCommandReplay().getPrimary().getUser();
- val password = isisConfiguration.getExtensions().getCommandReplay().getPrimary().getPassword();
+ val baseUrl = isisConfiguration.getExtensions().getCommandReplay().getPrimaryAccess().getBaseUrlRestful();
+ val user = isisConfiguration.getExtensions().getCommandReplay().getPrimaryAccess().getUser();
+ val password = isisConfiguration.getExtensions().getCommandReplay().getPrimaryAccess().getPassword();
if( !baseUrl.isPresent()||
!user.isPresent() ||
!password.isPresent()) {
- log.info("init() - skipping, one or more 'isis.extensions.command-replay.primary' configuration constants missing");
+ log.warn("init() - skipping, one or more 'isis.extensions.command-replay.primary' configuration properties has not been set");
return;
}
@@ -120,7 +123,11 @@ public class TickingClockService {
private void ensureInitialized() {
if(!isInitialized()) {
throw new IllegalStateException(
- "Not initialized. Make sure that the application is configured to run as a replay secondary");
+ "Not initialized. " +
+ "Make sure that the application is configured as a " +
+ "replay secondary by configuring the " +
+ "'isis.extensions.command-replay.primary' " +
+ "configuration properties.");
}
}
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/config/SecondaryConfig.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/config/SecondaryConfig.java
new file mode 100644
index 0000000..00f3a4f
--- /dev/null
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/config/SecondaryConfig.java
@@ -0,0 +1,54 @@
+package org.apache.isis.extensions.commandreplay.secondary.config;
+
+import java.util.List;
+
+import javax.inject.Named;
+import javax.validation.constraints.NotNull;
+
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
+
+import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.core.config.IsisConfiguration;
+
+import lombok.Getter;
+import lombok.val;
+import lombok.extern.log4j.Log4j2;
+
+@Service
+@Named("isisExtensionsCommandReplaySecondary.SecondaryConfig")
+@Order(OrderPrecedence.MIDPOINT)
+@Log4j2
+public class SecondaryConfig {
+
+ @Getter final String primaryUser;
+ @Getter final String primaryPassword;
+ @Getter final String primaryBaseUrlRestful;
+ @Getter final String primaryBaseUrlWicket;
+ @Getter final int batchSize;
+
+ @Getter final String quartzUser;
+ @Getter final List<String> quartzRoles;
+
+ public SecondaryConfig(@NotNull final IsisConfiguration isisConfiguration) {
+ val config = isisConfiguration.getExtensions().getCommandReplay();
+
+ val primaryAccess = config.getPrimaryAccess();
+ primaryUser = primaryAccess.getUser().orElse(null);
+ primaryPassword = primaryAccess.getPassword().orElse(null);
+ primaryBaseUrlRestful = primaryAccess.getBaseUrlRestful().orElse(null);
+ primaryBaseUrlWicket = primaryAccess.getBaseUrlWicket().orElse(null);
+ batchSize = config.getBatchSize();
+
+ quartzUser = config.getQuartzSession().getUser();
+ quartzRoles = config.getQuartzSession().getRoles();
+ }
+
+ public boolean isConfigured() {
+ return primaryUser != null &&
+ primaryPassword != null &&
+ primaryBaseUrlRestful != null &&
+ quartzUser != null &&
+ quartzRoles != null;
+ }
+}
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/executor/CommandExecutorServiceWithTime.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/executor/CommandExecutorServiceWithTime.java
similarity index 84%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/executor/CommandExecutorServiceWithTime.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/executor/CommandExecutorServiceWithTime.java
index 6169627..392f886 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/executor/CommandExecutorServiceWithTime.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/executor/CommandExecutorServiceWithTime.java
@@ -14,25 +14,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.isis.extensions.commandreplay.impl.executor;
+package org.apache.isis.extensions.commandreplay.secondary.executor;
-import java.sql.Timestamp;
-import java.util.concurrent.Callable;
import java.util.function.Supplier;
import javax.inject.Named;
import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
-import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.OrderPrecedence;
import org.apache.isis.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.applib.services.command.Command;
import org.apache.isis.applib.services.command.CommandExecutorService;
-import org.apache.isis.extensions.commandreplay.impl.clock.TickingClockService;
+import org.apache.isis.extensions.commandreplay.secondary.clock.TickingClockService;
import org.apache.isis.schema.cmd.v2.CommandDto;
-import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
/**
@@ -43,7 +42,10 @@ import lombok.extern.log4j.Log4j2;
* It then delegates down to the default implementation.
* </p>
*/
-@DomainService()
+@Service
+@Named("isisExtensionsCommandReplaySecondary.CommandExecutorServiceWithTime")
+@Order(OrderPrecedence.MIDPOINT - 10) // before CommandExecutorServiceDefault
+@Qualifier("WithTime")
@Log4j2
public class CommandExecutorServiceWithTime implements CommandExecutorService {
@@ -51,10 +53,8 @@ public class CommandExecutorServiceWithTime implements CommandExecutorService {
final TickingClockService tickingClockService;
public CommandExecutorServiceWithTime(
- //@Named("isisRuntimeServices.CommandExecutorServiceDefault")
- @Qualifier("Default")
- CommandExecutorService delegate
- , TickingClockService tickingClockService) {
+ @Qualifier("Default") final CommandExecutorService delegate,
+ final TickingClockService tickingClockService) {
this.delegate = delegate;
this.tickingClockService = tickingClockService;
}
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/fetch/CommandFetcher.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/fetch/CommandFetcher.java
similarity index 72%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/fetch/CommandFetcher.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/fetch/CommandFetcher.java
index 27ec9a7..e4b9d47 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/fetch/CommandFetcher.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/fetch/CommandFetcher.java
@@ -1,18 +1,24 @@
-package org.apache.isis.extensions.commandreplay.impl.fetch;
+package org.apache.isis.extensions.commandreplay.secondary.fetch;
import java.net.URI;
import java.util.List;
import java.util.UUID;
+import javax.annotation.Nullable;
import javax.inject.Inject;
+import javax.inject.Named;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
-import org.apache.isis.applib.annotation.DomainService;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
+
+import org.apache.isis.applib.annotation.OrderPrecedence;
import org.apache.isis.applib.services.jaxb.JaxbService;
import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandreplay.impl.SecondaryStatus;
-import org.apache.isis.extensions.commandreplay.impl.StatusException;
+import org.apache.isis.extensions.commandreplay.secondary.SecondaryStatus;
+import org.apache.isis.extensions.commandreplay.secondary.StatusException;
+import org.apache.isis.extensions.commandreplay.secondary.config.SecondaryConfig;
import org.apache.isis.extensions.jaxrsclient.applib.client.JaxRsClient;
import org.apache.isis.extensions.jaxrsclient.applib.client.JaxRsResponse;
import org.apache.isis.extensions.jaxrsclient.impl.client.JaxRsClientDefault;
@@ -22,28 +28,30 @@ import org.apache.isis.schema.cmd.v2.CommandsDto;
import lombok.extern.log4j.Log4j2;
-@DomainService()
+@Service()
+@Named("isisExtensionsCommandReplaySecondary.CommandFetcher")
+@Order(OrderPrecedence.MIDPOINT)
@Log4j2
public class CommandFetcher {
static final String URL_SUFFIX =
- "services/isisExtensionsCommandReplay.CommandReplayOnPrimaryService/actions/findCommandsOnPrimarySince/invoke";
+ "services/isisExtensionsCommandReplayPrimary.CommandReplayOnPrimaryService/actions/findCommandsOnPrimarySince/invoke";
/**
* Replicates a single command.
*
- * @param previousHwm
+ * @param previousHwmIfAny
* @return
* @throws StatusException
*/
public CommandDto fetchCommand(
- final CommandJdo previousHwm)
+ @Nullable final CommandJdo previousHwmIfAny)
throws StatusException {
log.debug("finding command on primary ...");
- final CommandsDto commandsDto = fetchCommands(previousHwm);
+ final CommandsDto commandsDto = fetchCommands(previousHwmIfAny);
if (commandsDto == null) {
return null;
@@ -58,10 +66,12 @@ public class CommandFetcher {
/**
* @return - the commands, or <tt>null</tt> if none were found
* @throws StatusException
- * @param previousHwm
+ * @param previousHwmIfAny
*/
- private CommandsDto fetchCommands(final CommandJdo previousHwm) throws StatusException {
- final UUID transactionId = previousHwm != null ? previousHwm.getUniqueId() : null;
+ private CommandsDto fetchCommands(final CommandJdo previousHwmIfAny)
+ throws StatusException {
+
+ final UUID transactionId = previousHwmIfAny != null ? previousHwmIfAny.getUniqueId() : null;
log.debug("finding commands on primary ...");
@@ -79,15 +89,15 @@ public class CommandFetcher {
}
- private URI buildUri(final UUID transactionId) {
+ private URI buildUri(final UUID uniqueId) {
final UriBuilder uriBuilder = UriBuilder.fromUri(
- transactionId != null
+ uniqueId != null
? String.format(
- "%s%s?transactionId=%s&batchSize=%d",
- primaryConfig.getBaseUrl(), URL_SUFFIX, transactionId, primaryConfig.getBatchSize())
+ "%s%s?uniqueId=%s&batchSize=%d",
+ secondaryConfig.getPrimaryBaseUrlRestful(), URL_SUFFIX, uniqueId, secondaryConfig.getBatchSize())
: String.format(
"%s%s?batchSize=%d",
- primaryConfig.getBaseUrl(), URL_SUFFIX, primaryConfig.getBatchSize())
+ secondaryConfig.getPrimaryBaseUrlWicket(), URL_SUFFIX, secondaryConfig.getBatchSize())
);
final URI uri = uriBuilder.build();
log.info("uri = {}", uri);
@@ -98,8 +108,8 @@ public class CommandFetcher {
final JaxRsResponse response;
final JaxRsClient jaxRsClient = new JaxRsClientDefault();
try {
- final String user = primaryConfig.getUser();
- final String password = primaryConfig.getPassword();
+ final String user = secondaryConfig.getPrimaryUser();
+ final String password = secondaryConfig.getPrimaryPassword();
response = jaxRsClient.get(uri, CommandsDto.class, JaxRsClient.ReprType.ACTION_RESULT, user, password);
int status = response.getStatus();
if(status != Response.Status.OK.getStatusCode()) {
@@ -142,6 +152,6 @@ public class CommandFetcher {
}
@Inject
- PrimaryConfig primaryConfig;
+ SecondaryConfig secondaryConfig;
}
\ No newline at end of file
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/job/ReplicateAndReplayJob.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/job/ReplicateAndReplayJob.java
similarity index 80%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/job/ReplicateAndReplayJob.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/job/ReplicateAndReplayJob.java
index cde212b..4c6000a 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/job/ReplicateAndReplayJob.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/job/ReplicateAndReplayJob.java
@@ -1,4 +1,4 @@
-package org.apache.isis.extensions.commandreplay.impl.job;
+package org.apache.isis.extensions.commandreplay.secondary.job;
import javax.inject.Inject;
@@ -12,11 +12,10 @@ import org.apache.isis.core.runtime.iactn.IsisInteractionFactory;
import org.apache.isis.core.security.authentication.AuthenticationSession;
import org.apache.isis.core.security.authentication.standard.SimpleSession;
-import org.apache.isis.extensions.commandreplay.impl.fetch.SecondaryConfig;
-import org.apache.isis.extensions.commandreplay.impl.job.callables.IsTickingClockInitialized;
-import org.apache.isis.extensions.commandreplay.impl.job.callables.ReplicateAndRunCommands;
-import org.apache.isis.extensions.commandreplay.impl.fetch.PrimaryConfig;
-import org.apache.isis.extensions.commandreplay.impl.SecondaryStatus;
+import org.apache.isis.extensions.commandreplay.secondary.config.SecondaryConfig;
+import org.apache.isis.extensions.commandreplay.secondary.jobcallables.IsTickingClockInitialized;
+import org.apache.isis.extensions.commandreplay.secondary.jobcallables.ReplicateAndRunCommands;
+import org.apache.isis.extensions.commandreplay.secondary.SecondaryStatus;
import lombok.val;
import lombok.extern.log4j.Log4j2;
@@ -26,7 +25,6 @@ import lombok.extern.log4j.Log4j2;
@Log4j2
public class ReplicateAndReplayJob implements Job {
- @Inject PrimaryConfig primaryConfig;
@Inject SecondaryConfig secondaryConfig;
AuthenticationSession authSession;
@@ -36,8 +34,8 @@ public class ReplicateAndReplayJob implements Job {
// figure out if this instance is configured to run as primary or secondary
new SecondaryStatusData(quartzContext);
- if(primaryConfig.isConfigured() && secondaryConfig.isConfigured()) {
- authSession = new SimpleSession(secondaryConfig.getUser(), secondaryConfig.getRoles());
+ if(secondaryConfig.isConfigured()) {
+ authSession = new SimpleSession(secondaryConfig.getPrimaryUser(), secondaryConfig.getQuartzRoles());
exec(quartzContext);
}
}
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/job/SecondaryStatusData.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/job/SecondaryStatusData.java
similarity index 87%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/job/SecondaryStatusData.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/job/SecondaryStatusData.java
index d9f3d73..1866787 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/job/SecondaryStatusData.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/job/SecondaryStatusData.java
@@ -1,8 +1,8 @@
-package org.apache.isis.extensions.commandreplay.impl.job;
+package org.apache.isis.extensions.commandreplay.secondary.job;
import org.quartz.JobExecutionContext;
-import org.apache.isis.extensions.commandreplay.impl.SecondaryStatus;
+import org.apache.isis.extensions.commandreplay.secondary.SecondaryStatus;
import org.apache.isis.extensions.quartz.context.JobExecutionData;
import lombok.val;
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/job/callables/IsTickingClockInitialized.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/IsTickingClockInitialized.java
similarity index 75%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/job/callables/IsTickingClockInitialized.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/IsTickingClockInitialized.java
index 9a8b6c9..c13f70f 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/job/callables/IsTickingClockInitialized.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/IsTickingClockInitialized.java
@@ -1,11 +1,11 @@
-package org.apache.isis.extensions.commandreplay.impl.job.callables;
+package org.apache.isis.extensions.commandreplay.secondary.jobcallables;
import java.util.concurrent.Callable;
import javax.inject.Inject;
import org.apache.isis.applib.services.xactn.TransactionService;
-import org.apache.isis.extensions.commandreplay.impl.clock.TickingClockService;
+import org.apache.isis.extensions.commandreplay.secondary.clock.TickingClockService;
public class IsTickingClockInitialized implements Callable<Boolean> {
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/job/callables/ReplicateAndRunCommands.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
similarity index 58%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/job/callables/ReplicateAndRunCommands.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
index 2b805c7..f345ed5 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/job/callables/ReplicateAndRunCommands.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
@@ -1,4 +1,4 @@
-package org.apache.isis.extensions.commandreplay.impl.job.callables;
+package org.apache.isis.extensions.commandreplay.secondary.jobcallables;
import java.util.Optional;
import java.util.concurrent.Callable;
@@ -10,15 +10,25 @@ import org.apache.isis.applib.services.xactn.TransactionService;
import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
import org.apache.isis.extensions.commandlog.impl.jdo.ReplayState;
-import org.apache.isis.extensions.commandreplay.impl.SecondaryStatus;
-import org.apache.isis.extensions.commandreplay.impl.StatusException;
-import org.apache.isis.extensions.commandreplay.impl.analysis.CommandReplayAnalysisService;
-import org.apache.isis.extensions.commandreplay.impl.fetch.CommandFetcher;
-import org.apache.isis.extensions.commandreplay.impl.spi.ReplayCommandExecutionController;
+import org.apache.isis.extensions.commandreplay.secondary.SecondaryStatus;
+import org.apache.isis.extensions.commandreplay.secondary.StatusException;
+import org.apache.isis.extensions.commandreplay.secondary.analysis.CommandReplayAnalysisService;
+import org.apache.isis.extensions.commandreplay.secondary.fetch.CommandFetcher;
+import org.apache.isis.extensions.commandreplay.secondary.spi.ReplayCommandExecutionController;
import lombok.val;
import lombok.extern.log4j.Log4j2;
+/**
+ * Encodes the algorithm for fetching commands from the primary, and
+ * replaying on the secondary.
+ *
+ * <p>
+ * This class is instantiated each time the Quartz job
+ * (<code>{@link org.apache.isis.extensions.commandreplay.secondary.job.ReplicateAndReplayJob}</code>)
+ * files.
+ * </p>
+ */
@Log4j2
public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
@@ -29,7 +39,6 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
@Inject CommandReplayAnalysisService analysisService;
@Inject Optional<ReplayCommandExecutionController> controller;
-
@Override
public SecondaryStatus call() throws Exception {
try {
@@ -42,77 +51,53 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
private void doCall() throws StatusException {
- CommandJdo hwmCommand = null;
if(!isRunning()) {
log.debug("ReplicateAndRunCommands is paused");
return;
}
+ CommandJdo replicatedHwm = null;
while(isRunning()) {
- if(hwmCommand == null) {
+ if(replicatedHwm == null) {
// first time through the loop we need to find the HWM command
// on the secondary. On subsequent iterations we use the
// command from before as the HWM
- log.debug("searching for hwm on secondary ...");
- hwmCommand = commandJdoRepository.findReplayedHwm();
+ replicatedHwm = commandJdoRepository.findReplicatedHwm();
}
- if(hwmCommand == null) {
- log.debug("could not find HWM on secondary, breaking");
+ if(replicatedHwm != null && replicatedHwm.getReplayState().isFailed()) {
+ log.info("Command {} hit replay error", replicatedHwm.getUniqueId());
return;
}
- log.debug("current hwm {} @ {} : {}",
- hwmCommand.getUniqueId(), hwmCommand.getTimestamp(),
- hwmCommand.getLogicalMemberIdentifier());
-
-
- boolean fetchNext;
- if(hwmCommand.getReplayState() == null || hwmCommand.getReplayState() == ReplayState.PENDING) {
- // the HWM has not been replayed.
- // this might be because it has been marked for retry by the administrator.
- // so, we will just use it directly
+ if(isFetchRequired(replicatedHwm)) {
- fetchNext = false;
- } else {
- //
- // check that the current HWM was replayed successfully, otherwise break out
- //
- if(hwmCommand.getReplayState().isFailed()) {
- log.info("Command xactnId={} hit replay error", hwmCommand.getUniqueId());
- return;
- }
- fetchNext = true;
- }
-
- if(fetchNext) {
- //
// replicate next command from primary (if any)
- //
- val commandDto = commandFetcher.fetchCommand(hwmCommand);
+ val commandDto = commandFetcher.fetchCommand(replicatedHwm);
if (commandDto == null) {
log.info("No more commands found, breaking out");
return;
}
- hwmCommand = transactionService.executeWithinTransaction(
+ replicatedHwm = transactionService.executeWithinTransaction(
() -> commandJdoRepository.saveForReplay(commandDto));
}
- log.info("next HWM transactionId = {}", hwmCommand.getUniqueId());
+ assert replicatedHwm != null;
+ log.info("next HWM {}", replicatedHwm.getUniqueId());
//
// run command
//
- executeCommandInTran(hwmCommand);
+ executeCommandInTran(replicatedHwm);
//
// find child commands, and run them
//
- val parent = hwmCommand;
+ val parent = replicatedHwm;
val childCommands =
transactionService.executeWithinTransaction(
() -> commandJdoRepository.findByParent(parent));
@@ -130,6 +115,30 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
}
}
+ private boolean isFetchRequired(final CommandJdo replicatedHwm) {
+
+ boolean fetchNext;
+ if(replicatedHwm == null) {
+ log.debug("could not find any replicated HWM");
+ return true;
+
+ }
+
+ val notYetReplayed = replicatedHwm.getReplayState() == null || replicatedHwm.getReplayState() == ReplayState.PENDING;
+ // the replicated HWM command might not yet been replayed.
+ // For example, this could be because it has been marked for retry
+ // by the administrator. if so, no need to fetch another command from the primary.
+
+ log.debug("current replicated hwm {} @ {} : {} has " +
+ (notYetReplayed? "NOT yet ": "") +
+ "been replayed",
+ replicatedHwm.getUniqueId(), replicatedHwm.getTimestamp(),
+ replicatedHwm.getLogicalMemberIdentifier());
+
+ return !notYetReplayed;
+
+ }
+
private void executeCommandInTran(final CommandJdo command) {
val commandDto = command.getCommandDto();
transactionService.executeWithinTransaction(
@@ -148,5 +157,4 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
}
-
}
\ No newline at end of file
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_exclude.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_exclude.java
similarity index 66%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_exclude.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_exclude.java
index 05ef148..64676d2 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_exclude.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_exclude.java
@@ -1,4 +1,8 @@
-package org.apache.isis.extensions.commandreplay.impl.mixins;
+package org.apache.isis.extensions.commandreplay.secondary.mixins;
+
+import java.util.Optional;
+
+import javax.inject.Inject;
import org.apache.isis.applib.annotation.Action;
import org.apache.isis.applib.annotation.MemberOrder;
@@ -6,25 +10,24 @@ import org.apache.isis.applib.annotation.SemanticsOf;
import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
import org.apache.isis.extensions.commandlog.impl.jdo.ReplayState;
+import org.apache.isis.extensions.commandreplay.secondary.config.SecondaryConfig;
+import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Action(
- semantics = SemanticsOf.NON_IDEMPOTENT_ARE_YOU_SURE,
- domainEvent = CommandJdo_exclude.ActionDomainEvent.class
-
+ semantics = SemanticsOf.NON_IDEMPOTENT_ARE_YOU_SURE,
+ domainEvent = CommandJdo_exclude.ActionDomainEvent.class
)
+@RequiredArgsConstructor
@Log4j2
public class CommandJdo_exclude {
public static class ActionDomainEvent
extends IsisModuleExtCommandLogImpl.ActionDomainEvent<CommandJdo_exclude> { }
- private final CommandJdo commandJdo;
- public CommandJdo_exclude(CommandJdo commandJdo) {
- this.commandJdo = commandJdo;
- }
+ final CommandJdo commandJdo;
@MemberOrder(name = "executeIn", sequence = "2")
public CommandJdo act() {
@@ -33,7 +36,7 @@ public class CommandJdo_exclude {
}
public boolean hideAct() {
- return commandJdo.getReplayState() == null;
+ return !secondaryConfig.isPresent() || !secondaryConfig.get().isConfigured() ;
}
public String disableAct() {
final boolean notInError =
@@ -43,4 +46,6 @@ public class CommandJdo_exclude {
: null;
}
+ @Inject Optional<SecondaryConfig> secondaryConfig;
+
}
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_openOnPrimary.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_openOnPrimary.java
new file mode 100644
index 0000000..d7f0b61
--- /dev/null
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_openOnPrimary.java
@@ -0,0 +1,54 @@
+package org.apache.isis.extensions.commandreplay.secondary.mixins;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.inject.Inject;
+
+import org.apache.isis.applib.ApplicationException;
+import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.SemanticsOf;
+import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
+import org.apache.isis.extensions.commandreplay.secondary.IsisModuleExtCommandReplaySecondary;
+import org.apache.isis.extensions.commandreplay.secondary.config.SecondaryConfig;
+
+import lombok.RequiredArgsConstructor;
+import lombok.val;
+
+@Action(
+ semantics = SemanticsOf.SAFE,
+ domainEvent = CommandJdo_openOnPrimary.ActionDomainEvent.class
+)
+@RequiredArgsConstructor
+public class CommandJdo_openOnPrimary<T> {
+
+ public static class ActionDomainEvent
+ extends IsisModuleExtCommandReplaySecondary.ActionDomainEvent<CommandJdo_openOnPrimary> { }
+
+ final CommandJdo commandJdo;
+
+ @MemberOrder(name = "transactionId", sequence = "1")
+ public URL act() {
+ val baseUrlPrefix = lookupBaseUrlPrefix();
+ val urlSuffix = bookmarkService.bookmarkFor(commandJdo).toString();
+
+ try {
+ return new URL(baseUrlPrefix + urlSuffix);
+ } catch (MalformedURLException e) {
+ throw new ApplicationException(e);
+ }
+ }
+ public boolean hideAct() {
+ return !secondaryConfig.isConfigured();
+ }
+
+ private String lookupBaseUrlPrefix() {
+ return secondaryConfig.getPrimaryBaseUrlWicket() + "entity/";
+ }
+
+ @Inject SecondaryConfig secondaryConfig;
+ @Inject BookmarkService bookmarkService;
+
+}
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_replayNext.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_replayNext.java
similarity index 73%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_replayNext.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_replayNext.java
index 040595a..00a4283 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/mixins/CommandJdo_replayNext.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_replayNext.java
@@ -1,4 +1,4 @@
-package org.apache.isis.extensions.commandreplay.impl.mixins;
+package org.apache.isis.extensions.commandreplay.secondary.mixins;
import javax.inject.Inject;
@@ -9,34 +9,34 @@ import org.apache.isis.applib.services.command.CommandExecutorService;
import org.apache.isis.applib.services.message.MessageService;
import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
-import org.apache.isis.extensions.commandreplay.impl.IsisModuleExtCommandReplayImpl;
-import org.apache.isis.extensions.commandreplay.impl.fetch.PrimaryConfig;
-import org.apache.isis.extensions.commandreplay.impl.StatusException;
+import org.apache.isis.extensions.commandreplay.secondary.IsisModuleExtCommandReplaySecondary;
+import org.apache.isis.extensions.commandreplay.secondary.StatusException;
+import org.apache.isis.extensions.commandreplay.secondary.config.SecondaryConfig;
import org.apache.isis.schema.cmd.v2.CommandDto;
-import org.apache.isis.extensions.commandreplay.impl.fetch.CommandFetcher;
-import org.apache.isis.extensions.commandreplay.impl.analysis.CommandReplayAnalysisService;
+import org.apache.isis.extensions.commandreplay.secondary.fetch.CommandFetcher;
+import org.apache.isis.extensions.commandreplay.secondary.analysis.CommandReplayAnalysisService;
+import lombok.RequiredArgsConstructor;
import lombok.val;
@Action(
- semantics = SemanticsOf.NON_IDEMPOTENT,
- domainEvent = CommandJdo_replayNext.ActionDomainEvent.class
+ semantics = SemanticsOf.NON_IDEMPOTENT,
+ domainEvent = CommandJdo_replayNext.ActionDomainEvent.class
)
+@RequiredArgsConstructor
public class CommandJdo_replayNext {
- public static class ActionDomainEvent extends IsisModuleExtCommandReplayImpl.ActionDomainEvent<CommandJdo_replayNext> { }
+ public static class ActionDomainEvent
+ extends IsisModuleExtCommandReplaySecondary.ActionDomainEvent<CommandJdo_replayNext> { }
- private final CommandJdo commandJdo;
- public CommandJdo_replayNext(CommandJdo commandJdo) {
- this.commandJdo = commandJdo;
- }
+ final CommandJdo commandJdo;
@MemberOrder(name = "executeIn", sequence = "3")
public CommandJdo act() throws StatusException {
// double check this is still the HWM
- final CommandJdo replayHwm = commandJdoRepository.findReplayedHwm();
+ final CommandJdo replayHwm = commandJdoRepository.findReplicatedHwm();
if(commandJdo != replayHwm) {
messageService.informUser("HWM has changed");
return replayHwm;
@@ -54,7 +54,6 @@ public class CommandJdo_replayNext {
return nextHwm;
}
-
private CommandJdo fetchNext() throws StatusException {
final CommandDto commandDto = commandFetcher.fetchCommand(this.commandJdo);
return commandDto == null
@@ -74,8 +73,12 @@ public class CommandJdo_replayNext {
}
}
+ public boolean hideAct() {
+ return !secondaryConfig.isConfigured();
+ }
+
public String disableAct() {
- final CommandJdo replayHwm = commandJdoRepository.findReplayedHwm();
+ final CommandJdo replayHwm = commandJdoRepository.findReplicatedHwm();
if(commandJdo != replayHwm) {
return "This action can only be performed against the 'HWM' command on the secondary";
@@ -90,17 +93,11 @@ public class CommandJdo_replayNext {
return null;
}
- public boolean hideAct() {
- return !primaryConfig.isConfigured();
- }
-
- @Inject
- CommandJdoRepository commandJdoRepository;
+ @Inject CommandJdoRepository commandJdoRepository;
@Inject CommandFetcher commandFetcher;
@Inject CommandExecutorService commandExecutorService;
- @Inject
- PrimaryConfig primaryConfig;
+ @Inject SecondaryConfig secondaryConfig;
@Inject MessageService messageService;
@Inject CommandReplayAnalysisService analysisService;
}
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_replayQueue.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_replayQueue.java
new file mode 100644
index 0000000..8a31458
--- /dev/null
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_replayQueue.java
@@ -0,0 +1,42 @@
+package org.apache.isis.extensions.commandreplay.secondary.mixins;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.isis.applib.annotation.Collection;
+import org.apache.isis.applib.annotation.CollectionLayout;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
+import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
+import org.apache.isis.extensions.commandreplay.secondary.IsisModuleExtCommandReplaySecondary;
+import org.apache.isis.extensions.commandreplay.secondary.config.SecondaryConfig;
+
+import lombok.RequiredArgsConstructor;
+
+@Collection(
+ domainEvent = CommandJdo_replayQueue.CollectionDomainEvent.class
+)
+@CollectionLayout(
+ defaultView = "table"
+)
+@RequiredArgsConstructor
+public class CommandJdo_replayQueue {
+
+ public static class CollectionDomainEvent
+ extends IsisModuleExtCommandReplaySecondary.CollectionDomainEvent<CommandJdo_replayQueue, CommandJdo> { }
+
+ final CommandJdo commandJdo;
+
+ @MemberOrder(sequence = "100.100")
+ public List<CommandJdo> coll() {
+ return commandJdoRepository.findReplayedOnSecondary();
+ }
+ public boolean hideColl() {
+ return !secondaryConfig.isConfigured();
+ }
+
+ @Inject SecondaryConfig secondaryConfig;
+ @Inject CommandJdoRepository commandJdoRepository;
+
+}
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/spi/ReplayCommandExecutionController.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/spi/ReplayCommandExecutionController.java
similarity index 88%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/spi/ReplayCommandExecutionController.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/spi/ReplayCommandExecutionController.java
index c2fec8d..bb2214e 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/spi/ReplayCommandExecutionController.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/spi/ReplayCommandExecutionController.java
@@ -1,4 +1,4 @@
-package org.apache.isis.extensions.commandreplay.impl.spi;
+package org.apache.isis.extensions.commandreplay.secondary.spi;
/**
* Optional SPI that allows the replicate and replay job to be paused if
diff --git a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/ui/CommandReplayOnSecondaryService.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/ui/CommandReplayOnSecondaryService.java
similarity index 74%
rename from extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/ui/CommandReplayOnSecondaryService.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/ui/CommandReplayOnSecondaryService.java
index 629fb3f..8fa72ee 100644
--- a/extensions/core/command-replay/impl/src/main/java/org/apache/isis/extensions/commandreplay/impl/ui/CommandReplayOnSecondaryService.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/ui/CommandReplayOnSecondaryService.java
@@ -1,9 +1,13 @@
-package org.apache.isis.extensions.commandreplay.impl.ui;
+package org.apache.isis.extensions.commandreplay.secondary.ui;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
import org.apache.isis.applib.annotation.Action;
import org.apache.isis.applib.annotation.ActionLayout;
@@ -11,12 +15,13 @@ import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.DomainServiceLayout;
import org.apache.isis.applib.annotation.MemberOrder;
import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.annotation.OrderPrecedence;
import org.apache.isis.applib.annotation.SemanticsOf;
import org.apache.isis.applib.services.jaxb.JaxbService;
import org.apache.isis.applib.value.Clob;
import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
-import org.apache.isis.extensions.commandreplay.impl.IsisModuleExtCommandReplayImpl;
+import org.apache.isis.extensions.commandreplay.secondary.IsisModuleExtCommandReplaySecondary;
import org.apache.isis.schema.cmd.v2.CommandDto;
import org.apache.isis.schema.cmd.v2.CommandsDto;
@@ -24,25 +29,27 @@ import lombok.val;
import lombok.extern.log4j.Log4j2;
@DomainService(
- nature = NatureOfService.VIEW,
- objectType = "isisExtensionsCommandReplay.CommandReplayOnSecondaryService"
+ nature = NatureOfService.VIEW,
+ objectType = "isisExtensionsCommandReplaySecondary.CommandReplayOnSecondaryService"
)
@DomainServiceLayout(
- named = "Activity",
- menuBar = DomainServiceLayout.MenuBar.SECONDARY
+ named = "Activity",
+ menuBar = DomainServiceLayout.MenuBar.SECONDARY
)
+@Named("isisExtensionsCommandReplaySecondary.CommandReplayOnSecondaryService")
+@Order(OrderPrecedence.MIDPOINT)
@Log4j2
public class CommandReplayOnSecondaryService {
public static abstract class ActionDomainEvent
- extends IsisModuleExtCommandReplayImpl.ActionDomainEvent<CommandReplayOnSecondaryService> { }
+ extends IsisModuleExtCommandReplaySecondary.ActionDomainEvent<CommandReplayOnSecondaryService> { }
public static class FindReplayHwmOnSecondaryDomainEvent extends ActionDomainEvent { }
@Action(domainEvent = FindReplayHwmOnSecondaryDomainEvent.class, semantics = SemanticsOf.SAFE)
@ActionLayout(cssClassFa = "fa-bath")
@MemberOrder(sequence="60.1")
public CommandJdo findReplayHwmOnSecondary() {
- return commandJdoRepository.findReplayedHwm();
+ return commandJdoRepository.findReplicatedHwm();
}
diff --git a/extensions/core/command-replay/impl/src/test/java/org/apache/isis/extensions/commandreplay/impl/fetch/ReplicateAndReplayJob_Test.java b/extensions/core/command-replay/secondary/src/test/java/org/apache/isis/extensions/commandreplay/secondary/fetch/CommandFetcher_Test.java
similarity index 81%
rename from extensions/core/command-replay/impl/src/test/java/org/apache/isis/extensions/commandreplay/impl/fetch/ReplicateAndReplayJob_Test.java
rename to extensions/core/command-replay/secondary/src/test/java/org/apache/isis/extensions/commandreplay/secondary/fetch/CommandFetcher_Test.java
index 3b09f03..4fbc55b 100644
--- a/extensions/core/command-replay/impl/src/test/java/org/apache/isis/extensions/commandreplay/impl/fetch/ReplicateAndReplayJob_Test.java
+++ b/extensions/core/command-replay/secondary/src/test/java/org/apache/isis/extensions/commandreplay/secondary/fetch/CommandFetcher_Test.java
@@ -1,14 +1,12 @@
-package org.apache.isis.extensions.commandreplay.impl.fetch;
+package org.apache.isis.extensions.commandreplay.secondary.fetch;
import java.net.URI;
import javax.ws.rs.core.UriBuilder;
-
import org.junit.jupiter.api.Test;
import org.apache.isis.applib.services.jaxb.JaxbService;
-import org.apache.isis.extensions.commandreplay.impl.fetch.CommandFetcher;
import org.apache.isis.extensions.jaxrsclient.applib.client.JaxRsClient;
import org.apache.isis.extensions.jaxrsclient.applib.client.JaxRsResponse;
import org.apache.isis.extensions.jaxrsclient.impl.client.JaxRsClientDefault;
@@ -17,10 +15,10 @@ import org.apache.isis.schema.cmd.v2.CommandsDto;
import lombok.val;
-public class ReplicateAndReplayJob_Test {
+public class CommandFetcher_Test {
@Test
- public void testing_the_unmarshalling() throws Exception {
+ public void testing_the_unmarshalling() {
val jaxRsClient = new JaxRsClientDefault();
final UriBuilder uriBuilder = UriBuilder.fromUri(
String.format(
diff --git a/extensions/pom.xml b/extensions/pom.xml
index 68addd6..6e9540a 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -76,7 +76,13 @@
<dependency>
<groupId>org.apache.isis.extensions</groupId>
- <artifactId>isis-extensions-command-replay-impl</artifactId>
+ <artifactId>isis-extensions-command-replay-primary</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.isis.extensions</groupId>
+ <artifactId>isis-extensions-command-replay-secondary</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
diff --git a/mappings/jaxrsclient/impl/src/main/java/org/apache/isis/extensions/jaxrsclient/impl/client/JaxRsClientDefault.java b/mappings/jaxrsclient/impl/src/main/java/org/apache/isis/extensions/jaxrsclient/impl/client/JaxRsClientDefault.java
index 89a93c8..d4fd32f 100644
--- a/mappings/jaxrsclient/impl/src/main/java/org/apache/isis/extensions/jaxrsclient/impl/client/JaxRsClientDefault.java
+++ b/mappings/jaxrsclient/impl/src/main/java/org/apache/isis/extensions/jaxrsclient/impl/client/JaxRsClientDefault.java
@@ -14,6 +14,9 @@ import javax.ws.rs.core.Response;
import org.apache.isis.extensions.jaxrsclient.applib.client.JaxRsClient;
import org.apache.isis.extensions.jaxrsclient.applib.client.JaxRsResponse;
+import lombok.Getter;
+import lombok.Setter;
+
public class JaxRsClientDefault implements JaxRsClient {
protected final ClientBuilder clientBuilder;
@@ -98,12 +101,12 @@ public class JaxRsClientDefault implements JaxRsClient {
protected void configureInvocationBuilder(final Object invocationBuilder) {
}
- private static MediaType mediaTypeFor(final Class<?> dtoClass, final ReprType reprType) {
+ private MediaType mediaTypeFor(final Class<?> dtoClass, final ReprType reprType) {
return mediaTypeFor(dtoClass, reprType.getSuffix());
}
- private static MediaType mediaTypeFor(final Class<?> dtoClass, final String reprType) {
- // application/xml;profile="urn:org.restfulobjects:repr-types/action-result";x-ro-domain-type="org.apache.isis.schema.cmd.v1.CommandsDto"
+ private MediaType mediaTypeFor(final Class<?> dtoClass, final String reprType) {
+ // application/xml;profile="urn~org.restfulobjects~repr-types/action-result";x-ro-domain-type="org.apache.isis.schema.cmd.v1.CommandsDto"
return new MediaType("application", "xml",
new HashMap<String,String>() {{
put("profile", "urn:org.restfulobjects:repr-types/" + reprType);
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java
index 32b05a2..2b4a126 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java
@@ -57,9 +57,13 @@ public class ObjectActionArgHelper {
val paramMeta = parameters.getElseFail(i);
val paramSpec = paramMeta.getSpecification();
try {
- val argAdapter = new JsonParserHelper(resourceContext, paramSpec)
- .objectAdapterFor(argRepr);
- argAdapters.add(_Either.left(argAdapter));
+ if(paramMeta.isOptional() && argRepr == null) {
+ argAdapters.add(_Either.leftNullable(ManagedObject.empty(paramSpec)));
+ } else {
+ val argAdapter = new JsonParserHelper(resourceContext, paramSpec)
+ .objectAdapterFor(argRepr);
+ argAdapters.add(_Either.left(argAdapter));
+ }
} catch (Exception e) {
val veto = InteractionVeto.actionParamInvalid(