@@ -11,6 +11,8 @@ import static org.hibernate.criterion.Restrictions.*; | |||||
@Repository | @Repository | ||||
public class FlexRouterDAO extends AccountOwnedEntityDAO<FlexRouter> { | public class FlexRouterDAO extends AccountOwnedEntityDAO<FlexRouter> { | ||||
@Override protected String getNameField() { return "ip"; } | |||||
public List<FlexRouter> findEnabledAndRegistered() { | public List<FlexRouter> findEnabledAndRegistered() { | ||||
return list(criteria().add(and( | return list(criteria().add(and( | ||||
eq("enabled", true), | eq("enabled", true), | ||||
@@ -1,7 +1,7 @@ | |||||
package bubble.model.device; | package bubble.model.device; | ||||
import bubble.model.account.Account; | import bubble.model.account.Account; | ||||
import bubble.model.account.HasAccountNoName; | |||||
import bubble.model.account.HasAccount; | |||||
import com.fasterxml.jackson.annotation.JsonIgnore; | import com.fasterxml.jackson.annotation.JsonIgnore; | ||||
import lombok.Getter; | import lombok.Getter; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
@@ -31,7 +31,7 @@ import static org.cobbzilla.util.reflect.ReflectionUtil.copy; | |||||
@ECTypeURIs(baseURI=EP_FLEX_ROUTERS, listFields={"name", "enabled"}) | @ECTypeURIs(baseURI=EP_FLEX_ROUTERS, listFields={"name", "enabled"}) | ||||
@NoArgsConstructor @Accessors(chain=true) @Slf4j | @NoArgsConstructor @Accessors(chain=true) @Slf4j | ||||
@ECIndexes({ @ECIndex(unique=true, of={"account", "ip"}) }) | @ECIndexes({ @ECIndex(unique=true, of={"account", "ip"}) }) | ||||
public class FlexRouter extends IdentifiableBase implements HasAccountNoName { | |||||
public class FlexRouter extends IdentifiableBase implements HasAccount { | |||||
public static final String[] UPDATE_FIELDS = { "enabled", "active", "proxy_port", "auth_token" }; | public static final String[] UPDATE_FIELDS = { "enabled", "active", "proxy_port", "auth_token" }; | ||||
public static final String[] CREATE_FIELDS = ArrayUtil.append(UPDATE_FIELDS, "ip"); | public static final String[] CREATE_FIELDS = ArrayUtil.append(UPDATE_FIELDS, "ip"); | ||||
@@ -44,6 +44,8 @@ public class FlexRouter extends IdentifiableBase implements HasAccountNoName { | |||||
@ECIndex @Column(nullable=false, length=500) | @ECIndex @Column(nullable=false, length=500) | ||||
@Getter @Setter private String ip; | @Getter @Setter private String ip; | ||||
@JsonIgnore @Transient public String getName () { return getIp(); } | |||||
@ECSearchable(filter=true) @ECField(index=20) | @ECSearchable(filter=true) @ECField(index=20) | ||||
@ECIndex @Column(nullable=false) | @ECIndex @Column(nullable=false) | ||||
@JsonIgnore @Getter @Setter private Integer port = 0; | @JsonIgnore @Getter @Setter private Integer port = 0; | ||||
@@ -69,6 +71,7 @@ public class FlexRouter extends IdentifiableBase implements HasAccountNoName { | |||||
@ECIndex @Column(nullable=false) | @ECIndex @Column(nullable=false) | ||||
@Getter @Setter private Boolean active = true; | @Getter @Setter private Boolean active = true; | ||||
public boolean active() { return bool(active); } | public boolean active() { return bool(active); } | ||||
public boolean inactive() { return !active(); } | |||||
@ECSearchable @ECField(index=60, type=EntityFieldType.epoch_time, mode=EntityFieldMode.readOnly) | @ECSearchable @ECField(index=60, type=EntityFieldType.epoch_time, mode=EntityFieldMode.readOnly) | ||||
@Getter @Setter private Long lastSeen; | @Getter @Setter private Long lastSeen; | ||||
@@ -11,7 +11,8 @@ import org.glassfish.grizzly.http.server.Request; | |||||
import org.glassfish.jersey.server.ContainerRequest; | import org.glassfish.jersey.server.ContainerRequest; | ||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import static bubble.ApiConstants.getRemoteAddr; | |||||
import static bubble.service.device.FlexRouterService.pingFlexRouter; | |||||
import static org.cobbzilla.util.json.JsonUtil.COMPACT_MAPPER; | |||||
import static org.cobbzilla.util.json.JsonUtil.json; | import static org.cobbzilla.util.json.JsonUtil.json; | ||||
import static org.cobbzilla.wizard.resources.ResourceUtil.invalidEx; | import static org.cobbzilla.wizard.resources.ResourceUtil.invalidEx; | ||||
import static org.cobbzilla.wizard.resources.ResourceUtil.userPrincipal; | import static org.cobbzilla.wizard.resources.ResourceUtil.userPrincipal; | ||||
@@ -28,33 +29,21 @@ public class FlexRoutersResource extends AccountOwnedResource<FlexRouter, FlexRo | |||||
return !caller.admin(); | return !caller.admin(); | ||||
} | } | ||||
@Override protected FlexRouter findAlternate(Request req, ContainerRequest ctx, FlexRouter request) { | |||||
final String remoteAddr = getRemoteAddr(req); | |||||
return getDao().findByAccountAndIp(account.getUuid(), remoteAddr); | |||||
} | |||||
@Override protected FlexRouter setReferences(ContainerRequest ctx, Request req, Account caller, FlexRouter router) { | @Override protected FlexRouter setReferences(ContainerRequest ctx, Request req, Account caller, FlexRouter router) { | ||||
if (!router.hasProxyPort()) { | |||||
log.error("setReferences: no proxy port provided"); | |||||
throw invalidEx("err.proxyPort.required"); | |||||
} | |||||
if (!router.hasProxyPort()) throw invalidEx("err.proxyPort.required"); | |||||
router.setPort(router.getProxy_port()); | router.setPort(router.getProxy_port()); | ||||
final String ip = router.getIp(); | final String ip = router.getIp(); | ||||
final Device device = deviceService.findDeviceByIp(ip); | final Device device = deviceService.findDeviceByIp(ip); | ||||
if (device == null) { | |||||
log.error("setReferences: device not found: "+ip); | |||||
throw invalidEx("err.device.notFound"); | |||||
} | |||||
log.info("setReferences: found device with ip="+ip+": "+device.getUuid()); | |||||
// todo: send verification request to IP | |||||
if (device == null) throw invalidEx("err.device.notFound"); | |||||
if (!router.hasAuthToken()) { | |||||
log.error("setReferences: no auth_token provided"); | |||||
if (pingFlexRouter(router).inactive()) { | |||||
log.info("setReferences: router not active: "+json(router, COMPACT_MAPPER)); | |||||
throw invalidEx("err.token.required"); | throw invalidEx("err.token.required"); | ||||
} | } | ||||
if (!router.hasAuthToken()) throw invalidEx("err.token.required"); | |||||
router.setToken(router.getAuth_token()); | router.setToken(router.getAuth_token()); | ||||
log.info("setReferences: FlexRouter=\n"+json(router)+"\n"); | log.info("setReferences: FlexRouter=\n"+json(router)+"\n"); | ||||
@@ -28,7 +28,7 @@ public class FlexRouterService extends SimpleDaemon { | |||||
try { | try { | ||||
final List<FlexRouter> routers = flexRouterDAO.findEnabledAndRegistered(); | final List<FlexRouter> routers = flexRouterDAO.findEnabledAndRegistered(); | ||||
for (FlexRouter router : routers) { | for (FlexRouter router : routers) { | ||||
FlexRouter update = pingRouter(router); | |||||
FlexRouter update = pingFlexRouter(router); | |||||
if (update != null) { | if (update != null) { | ||||
flexRouterDAO.update(update); | flexRouterDAO.update(update); | ||||
} | } | ||||
@@ -38,7 +38,7 @@ public class FlexRouterService extends SimpleDaemon { | |||||
} | } | ||||
} | } | ||||
private FlexRouter pingRouter(FlexRouter router) { | |||||
public static FlexRouter pingFlexRouter(FlexRouter router) { | |||||
final String prefix = "pingRouter(" + router + "): "; | final String prefix = "pingRouter(" + router + "): "; | ||||
final HttpRequestBean request = new HttpRequestBean(POST, router.pingUrl(), router.pingObject()); | final HttpRequestBean request = new HttpRequestBean(POST, router.pingUrl(), router.pingObject()); | ||||
try { | try { | ||||